true && echo foo
将打印foo
.false && echo foo
不会打印foo
。bash -c "exit $a" && echo foo
将打印foo
取决于$a
.
最后一个有没有更优雅的写法?仅仅为了设置退出值就必须启动 shell 似乎有点麻烦。我在想这样的事情:
return $a && echo foo
exit $a && echo foo
exceptreturn
仅适用于函数,并且exit
将导致echo foo
永远不会运行。
在这种情况下,优雅意味着:
- 容易明白
- 便携的
- 易于阅读
- 容易写
- 容易记住
- 短的
- 高性能
例如,如果true
将退出代码作为参数(这是一个已记录的功能),那将非常优雅。
那么有没有更优雅的方式呢?
背景
可以使用它的地方之一是:
$ parallel 'setexitval {= $_%=3 =} || echo $?' ::: 0 1 2 3
拘萨罗南达的版本可能是最好的。很清楚发生了什么。写起来并不长而且麻烦。它易于记忆且便于携带。唯一的缺点是它分叉了另一个 shell(花费约 0.5 毫秒):
$ parallel '(exit {= $_%=3 =}) || echo $?' ::: 0 1 2 3
另一种情况是当您想要模拟错误情况时。比如说,如果您有一个长时间运行的程序,它设置了不同的退出代码,并且您正在编写一些将对不同退出代码做出反应的代码。您可以使用(exit $a)
它来模拟条件,而不必运行长时间运行的程序。
答案1
好吧,return
在一个函数中工作,所以让我们做一个:
$ ret() { return "${1-0}"; }
$ ret 1 || echo foo
foo
$ ret 123 ; echo $?
123
它比子 shell 需要更多的设置,但之后使用时间更短,并且不需要分叉子 shell。
答案2
使用以指定值退出的子 shell。
这将输出5
:
a=5; ( exit $a ) && echo foo; echo $?
这将输出foo
and 0
(注意,这个零是通过echo
后续设置的,而不是通过exit
子 shell 中的 来设置的):
a=0; ( exit $a ) && echo foo; echo $?
在您的缩写形式中(没有明显设置a
或$?
明确调查):
( exit $a ) && echo foo
我的答案是,只是从表面上看待这个问题,并将其作为一个有趣的测验来解决,“我们如何设置$?
(使用方便的符号)”。在这种情况下,我不会试图寻找任何更深层的含义、功能甚至背景(因为没有给出)。我也不判断解决方案的有效性、效率或可用性。有时,在我的回答中,我会说“......但不要那样做,因为......”,然后说“相反,这样做......”。在这种情况下,我选择将问题解释为一个简单的好奇测验。
现在向该问题添加了更多背景信息。
我对分叉子 shell 问题的看法是,像 GNU 这样的脚本configure
会这样做每时每刻,并且除非在非常紧密(长时间运行)的循环中完成,否则它并不是非常慢。
我不能过多谈论 GNU 中 GNU 的使用,parallel
因为我不是该软件的频繁用户。
答案3
一种选择(可能更快,但并不是更优雅):
test "$a" -eq 0 && echo foo
它执行echo
但没有将退出值设置为$a
,因此它是一个平庸的解决方案。
答案4
让我们检查一下您的假设:
true && echo foo
将打印 foo.正确,因为&&
遵循短路逻辑 AND;由于&&
和||
运算符中的左关联性,如果最左边的命令返回成功退出状态 0 (总是true
如此),则该运算符的最右边的命令将运行。false && echo foo
不会打印 foo.与上面解释的情况正好相反。bash -c "exit $a" && echo foo
将打印 foo 取决于$a
.本质上是错误的$a
控制假设&&
。因为&&
是 AND 逻辑,所以它仅识别两种状态 - 成功或失败,其中失败是大于 0 的任何退出状态。因此exit 1
andexit 2
和- 全部与;exit 3
无关。&&
失败就是失败,无论$a
价值如何;这就是为什么echo foo
不运行。
因此答案是不,没有更优雅的方式无论如何,做一些在错误假设下运作的事情。但是,如果您的目的是通过命令设置退出状态,那么使用 Kusalananda 的答案所建议的内容就足够了 - 子 shell。我个人认为这与bash -c
部分没有任何不同,除了子 shell 可以实现为子进程/分叉进程而不是单独的进程;还是不理想。请注意,$?
用户也不应该通过变量设置 - 它旨在用于传达成功或失败的命令。
$a
让我们暂时转移焦点。如果可以直接查的话为什么要设置$?
and呢?将价值放置在它不属于的地方是没有意义的,即放置在 中。我建议将焦点从“优雅”(无论这意味着什么)转移到“逻辑”和“工作”。echo foo
$a
$a
$?
好吧,让我们玩你的游戏吧。从中得到一点启发伊尔卡丘的回答。然而,这种方法消除了强制回显条件执行的需要。仅当它提供的变量指示成功时,它才会进行回显,并return
阻止其执行。
$ thing(){ [ "${1-0}" -eq 0 ] || return "$1" ; echo "foo"; }
$ thing
foo
$ thing 0
foo
$ thing 1
$ echo $?
1
$ thing 2
$ echo $?
2
可能不明显的是你可以做thing $a