如何在命令替换中使用检测失败

Nan*_*Hua 4 bash

如您所知, set -e 在执行命令时发现任何故障非常有用。但是我发现它使用起来很微妙,我不知道如何在以下场景中使用它:

==============第一个例子================================

set -e
function main() {    
  local X1="$(exp::notdefined)"    
  echo "Will reach here : ${LINENO}"    
  X2="$(exp::notdefined)"    
  echo "Will not reach here : ${LINENO}"
}
main 
Run Code Online (Sandbox Code Playgroud)

==============第二个例子================================

set -e    
function exp::tmp() {    
  echo "Now '$-' is "$-" : ${LINENO}"    
  false    
  return 0
}    
function main() {    
  X1="$(exp::tmp)"    
  echo "Will reach here : ${LINENO}. '\$X1' : ${X1}"    
  X2="$(set -e ; exp::tmp)"    
  echo "Will not reach here : ${LINENO}"
}    
main
Run Code Online (Sandbox Code Playgroud)

================================

第一个例子表明,如果我们对局部变量使用命令替换,那么即使没有找到被替换的命令,它也不会失败。我不知道如何检测这些类型的故障。

第二个示例表明,如果 bash 选项 (-e) 不会传播,除非我们在命令大括号内调用 set -e。有没有更好的方法来做到这一点?

Dav*_*ica 6

您请求在管道失败时立即退出-e,例如:

-e      Exit immediately if a pipeline (which may consistof a single simple
        command), a list, or a compound command (see SHELL GRAMMAR above), 
        exits with a non-zero status.
Run Code Online (Sandbox Code Playgroud)

错误的命令替换不会导致函数内失败的原因是因为local提供了它自己的返回状态

local [option] [name[=value] ...]
...除非在函数外使用 local、提供了无效名称或 name 是只读变量,否则返回状态0

分配失败的命令替换不会导致local返回非零值。因此,不会触发立即退出。

至于检查以下命令替换失败local,由于输出分配给变量,并且在命令替换失败的情况下返回不会是非零的,您必须通过检查变量内容本身来验证成功/失败的预期值。


Phi*_*hil 1

来自 bash 手册:

   Subshells spawned to execute command substitutions inherit the value of
   the -e option from the parent shell. When not in posix mode, bash
   clears the -e option in such subshells.
Run Code Online (Sandbox Code Playgroud)

当 bash 使用 ; 运行时,示例 2 的行为有所不同--posix。但是对于示例1,我找不到任何文档解释为什么local会导致这种情况。