If I fail to explicitly call exit
for certain function-based Bash scripts then there are additional unexpected executions for some functions. What is causing this? The behavior was first noticed while making a git alias as part of answering another user's question on StackOverflow. That alias was composed of this script (which runs the function twice instead of once):
#!/usr/bin/env bash
github(){
echo github;
};
twitter(){
echo twitter;
};
facebook(){
echo facebook;
};
if [[ $(type -t "$1") == "function" ]];
then
"$1";
else
echo "There is no defined function for $1";
fi;
But this slightly modified script executes as expected (runs the function only once):
#!/usr/bin/env bash
github(){
echo github;
};
twitter(){
echo twitter;
};
facebook(){
echo facebook;
};
if [[ $(type -t "$1") == "function" ]];
then
"$1";
exit 0;
else
echo "There is no defined function for $1";
exit 1;
fi;
Here is exactly what is happening when I run those scripts via a git alias (added set
command for debugging purposes only):
$ git config --global alias.encrypt-for '!set -evu -o pipefail;github(){ echo github;};twitter(){ echo twitter;};facebook(){ echo facebook;};if [[ $(type -t "$1") == "function" ]];then "$1"; exit 0; else echo "There is no defined function for $1"; exit 1; fi;'
$ git encrypt-for "github"
type -t "$1"
github
$ git config --global alias.encrypt-for '!set -evu -o pipefail;github(){ echo github;};twitter(){ echo twitter;};facebook(){ echo facebook;};if [[ $(type -t "$1") == "function" ]];then "$1"; else echo "There is no defined function for $1"; fi;'
$ git encrypt-for "github"
type -t "$1"
github
github
The output from set -x
:
$ git encrypt-for "github"
++ type -t github
+ [[ function == \f\u\n\c\t\i\o\n ]]
+ github
+ echo github
github
+ github
+ echo github
github
The output from replacing echo github
with echo "I am echo in github"
as a way of ruling out the echo
command as the source of the second function execution:
$ git encrypt-for "github"
++ type -t github
+ [[ function == \f\u\n\c\t\i\o\n ]]
+ github
+ echo 'I am echo in github'
I am echo in github
+ github
+ echo 'I am echo in github'
I am echo in github
The following is the simplest version of the alias/script which gives the undesired behavior of double execution:
g(){
echo "once";
};
$1;
And this is the resulting output from executing the simplified alias/script (which has the incorrect behavior of executing twice):
$ git config --global alias.encrypt-for '!g(){ echo "once";};$1;'
$ git encrypt-for g
once
once