问题
Sample bash script where I'm testing using variable expansion in command names:
test_command_w_variable_expansion_in_name.sh:
#!/bin/bash
# Gabriel Staples
# 21 Mar. 2020
echo "PATH = \"$PATH\""
# PATH="$HOME/bin:$PATH"
# echo "PATH = \"$PATH\""
# 1st, create a command in ~/bin to test here
mkdir -p ~/bin
echo -e "#!/bin/bash\necho \"This is a test script found in ~/bin.\"" > ~/bin/gs_test_script
chmod +x ~/bin/gs_test_script
# 1)
# command: `echo`
CMD_PREFIX="ec"
${CMD_PREFIX}ho "hey" # works
# exec "${CMD_PREFIX}ho" "hey" # works, but then prevents the code below from running!
# eval "${CMD_PREFIX}ho" "hey" # does NOT work, but also throws no error
# 2)
# command: `gs_test_script` from ~/bin
CMD_PREFIX="gs_test"
~/bin/gs_test_script # works!
gs_test_script # works!
${CMD_PREFIX}_script # works!
Output:
$ ./test_command_w_variable_expansion_in_name.sh
PATH = "/home/gabriel/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
hey
This is a test script found in ~/bin.
This is a test script found in ~/bin.
This is a test script found in ~/bin.
Questions:
Now, if I uncomment this line:
# exec "${CMD_PREFIX}ho" "hey" # works, but then prevents the code below from running!
, the code below it no longer runs, and I get this output instead! Notice I no longer get the 3 printouts ofThis is a test script found in ~/bin.
Why?$ ./test_command_w_variable_expansion_in_name.sh PATH = "/home/gabriel/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" hey hey
Also, the
eval
command just below it doesn't work. If I uncomment out that line I get the exact same erroneous output as posted just above, which still doesn't execute my call togs_test_script
three times like it should. Why?
回答1:
Because the exec command will replace the current bash process with the new command to be executed. It does not return to the calling process. So you should not use exec in your script.
exec [-cl] [-a name] [command [arguments]] If command is specified, it replaces the shell. No new process is created. The arguments become the arguments to command. If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is what login(1) does. The -c option causes command to be executed with an empty environment. If -a is supplied, the shell passes name as the zeroth argument to the executed command. If command cannot be executed for some reason, a non-interactive shell exits, unless the execfail shell option is enabled. In that case, it returns failure. An interactive shell returns failure if the file cannot be executed. If command is not specified, any redirections take effect in the current shell, and the return status is 0. If there is a redirection error, the return status is 1.
来源:https://stackoverflow.com/questions/60795129/no-code-will-run-after-exec-in-bash-script