Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash脚本中的'exec'之后不会运行任何代码_Bash_Variables_Exec_Eval - Fatal编程技术网

bash脚本中的'exec'之后不会运行任何代码

bash脚本中的'exec'之后不会运行任何代码,bash,variables,exec,eval,Bash,Variables,Exec,Eval,我在命令名中使用变量扩展测试的bash脚本示例: 测试\u命令\u w\u变量\u扩展\u在\u 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

我在命令名中使用变量扩展测试的bash脚本示例:

测试\u命令\u w\u变量\u扩展\u在\u 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!
输出:

$ ./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.
问题:

  • 现在,如果我取消注释这一行:
    #exec“${CMD_PREFIX}ho”“hey”#可以工作,但会阻止下面的代码运行,它下面的代码不再运行,我得到了这个输出!请注意,我不再获得
    的3个打印输出,这是在~/bin中找到的测试脚本。
    为什么?

    $ ./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
    
  • 另外,它下面的
    eval
    命令也不起作用。如果我取消注释该行,我会得到与上面发布的完全相同的错误输出,它仍然不会像应该的那样执行对
    gs\u test\u script
    的调用三次。为什么?


  • 因为exec命令将用要执行的新命令替换当前bash进程。它不会返回到调用进程。因此,您不应该在脚本中使用exec


    不要使用
    exec
    eval
    ,除非您了解它们的功能
    eval
    尤其因引起非常奇怪(有时甚至危险)的bug而名声不佳。将命令(或命令的一部分)放入变量中也是一件棘手的事情,如果可能的话,最好避免使用它。看看你从哪里抄的?我在
    man exec
    info exec
    exec--help
    中都没有看到它。对于bash内置程序,请使用
    help
    help exec
    我从
    help exec
    中的输出与上面显示的不同。也许我们有不同的版本。当我运行
    help
    时,顶部显示的版本是
    gnubash,版本4.4.20(1)-发行版(x86_64-pc-linux-GNU)
    。我在Ubuntu 18.04上@杜昌斌,你在运行什么版本的GNUBash?您是否从help exec获得了该输出?@Gabriel:这是bash 3.2。类似于OSX上的2007(因为他们不喜欢bash 4及以上版本的许可)。(是的,它来自
    帮助执行
      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.