Bash:设置状态的优雅方式?

Ole*_*nge 5 bash exit-status

  • true && echo foo将打印foo
  • false && echo foo不会打印foo
  • bash -c "exit $a" && echo foofoo根据$a.

有没有更优雅的方式来写最后一个?仅仅为了设置退出值而启动 shell 似乎有点多。我在想这样的事情:

  • return $a && echo foo
  • exit $a && echo foo

除了return仅适用于函数并且exit会导致echo foo永远不会运行。

优雅在这种情况下意味着:

  • 容易理解
  • 便携的
  • 易于阅读
  • 容易写
  • 容易记住
  • 短的
  • 高性能

例如如果 true将退出代码作为参数(这是一个文档化的特性),它会非常优雅。

那么有没有更优雅的方式呢?

背景

可以使用的地方之一是:

$ parallel 'setexitval {= $_%=3 =} || echo $?' ::: 0 1 2 3  
Run Code Online (Sandbox Code Playgroud)

Kusalananda 的版本可能是最好的。很清楚发生了什么。写起来不长也不麻烦。它易于记忆和便携。唯一的缺点是它分叉了另一个 shell(它花费了大约 0.5 毫秒):

$ parallel '(exit {= $_%=3 =}) || echo $?' ::: 0 1 2 3  
Run Code Online (Sandbox Code Playgroud)

另一种情况是当您想要模拟错误条件时。比如说,如果你有一个长时间运行的程序,它设置了不同的退出代码,并且你正在编写一些可以对不同退出代码做出反应的东西。不必运行长时间运行的程序,您可以使用(exit $a)来模拟条件。

ilk*_*chu 13

好吧,return在一个函数中工作,所以让我们做一个:

$ ret() { return "${1-0}"; }
$ ret 1 || echo foo
foo
$ ret 123 ; echo $?
123
Run Code Online (Sandbox Code Playgroud)

它比子shell需要更多的设置,但之后使用时间更短,并且不需要分叉子shell。


Kus*_*nda 8

使用以指定值退出的子shell。

这将输出5

a=5; ( exit $a ) && echo foo; echo $?
Run Code Online (Sandbox Code Playgroud)

这将输出foo0(注意,这个零是由echo成功设置的,而不是exit在子shell中设置的):

a=0; ( exit $a ) && echo foo; echo $?
Run Code Online (Sandbox Code Playgroud)

以您的缩写形式(没有明显设置a$?明确调查):

( exit $a ) && echo foo
Run Code Online (Sandbox Code Playgroud)

我的答案是从表面上看问题并将其作为一个奇怪的测验来解决,“我们如何设置$?(使用方便的符号)”。在这种情况下,我没有尝试搜索任何更深层次的含义或功能甚至上下文(因为给出了 non )。我也不判断解决方案的有效性、效率或可用性。有时,在我的回答中,我确实会说“……但不要那样做,因为……”,然后是“相反,做这个……”。在这种情况下,我选择将问题解释为简单的好奇测验。


现在为问题添加了进一步的背景。

我对 fork 子 shell 问题的看法是,像 GNU 这样的脚本一直在configure执行此操作,并且除非在非常紧密(长时间运行)的循环中完成,否则它不会非常慢。

关于在 GNU 中/与 GNU 一起使用,我不能说太多,parallel因为我不是该软件的频繁用户。

  • @mtraceur 我明白你在说什么,但我相信问题的重点是一种符号,我将“启动 shell”的问题解释为“`bach -c “exit $a”` 也是很多东西要打字”。 (2认同)

Ole*_*nge 6

一种选择(可能更快但不是更优雅):

test "$a" -eq 0 && echo foo
Run Code Online (Sandbox Code Playgroud)

它执行echo但没有将退出值设置为$a,因此它是一个平庸的解决方案。