保留 $?

zwo*_*wol 7 posix code-generation sh

仅使用 POSIX shell 的功能,是否有一个“简单命令”,它什么都不做并且不会改变$? 人们通常描述:为 shell 的无操作命令的值,但这总是设置$?为零,所以这不是我想要的想。

这是生成 shell 脚本的程序所需要的。在几个地方它需要发出一个 if-then-else 块

if CONDITION
then
    TRUE-COMMANDS
else
    FALSE-COMMANDS
fi
Run Code Online (Sandbox Code Playgroud)

但是,因为进一步的并发症的,我宁可不尝试,现在来解释,它不能可靠地告诉是否TRUE-COMMANDSFALSE-COMMANDS是空的。空的 then 或 else 子句将是 shell 语法错误。

:可以放在then-clause的开头以处理为TRUE-COMMANDS空,但这不会起作用,FALSE-COMMANDS因为它会破坏$?并且FALSE-COMMANDS可能想要查看$?条件设置的值。出于同样的原因,:不能放在后面 FALSE-COMMANDS——if-then-else后面的代码可能希望$?从 if-then-else 中的最后一个操作中看到。

可以避免的奖励积分:

  • 分叉:(exit $?)完成这项工作,但在生成的脚本中有太多这样的条件块,它会产生可测量的减速。

  • 功能:给定nop () { return $? }然后nop完成工作,但由于我不想涉及的更多复杂性,nop为所有需要它的地方足够早地定义是不切实际的。

kva*_*our 1

最简单的方法是使用简单的分配。而不是使用:,做_rc=$?

if condition; then
   [ list-true ]     # optional 
   _rc=$?
else
   [ list-false ]    # optional
   _rc=$?
fi
( exit $_rc )        # optional
list-post-if
Run Code Online (Sandbox Code Playgroud)

使用此变量_rc,您可以存储最后执行的命令的退出状态,无论这是还是或condition中的最后一个命令。list-truelist-false

  • 支持此方法的论据是分配的开销较低。
  • 反对的论点是至少需要重写list-post-if以利用_rc而不是$?
  • 如果后者不可能,或者太乏味,您可能会考虑(exit $_rc)在条件语句后面添加一个。然而,这需要一个子 shell,但它只是一个。