在zsh中
echo 'a string' > test.txt
echo $?
0
和
[[ $(echo 'a string') ]]
echo $?
0
然而
[[ $(echo 'a string' > test.txt) ]]
echo $?
1
另一个例子
curl -so 'curl-8.2.1.tar.gz' https://curl.se/download/curl-8.2.1.tar.gz
echo $?
0
或者
[[ $(curl -so 'curl-8.2.1.tar.gz' https://curl.se/download/curl-8.2.1.tar.gz) ]]
echo $?
1
我的问题:
- 这是因为输出重定向吗?如果不是,是什么原因造成的?
- 命令执行成功:
a string
出现在test.txt
并且curl将文件下载到我指定的输出文件中,为什么评估结果为false
? - 在脚本中是否有一种明智的方法来处理这个问题?假设我想执行某个命令,如果前一个命令执行成功(但
false
仍然返回),应该如何执行?我可以添加第二次检查来查看该行是否出现或文件是否已下载,但首先就不需要评估命令是否成功执行。
更多完整性示例(可读性与“正确性”?):
if ( $(echo 'a string' > text.txt) ); then echo yes; else echo no;fi
yes
if (( $(echo 'a string' > text.txt) )); then echo yes; else echo no;fi
no
if $(echo 'a string' > text.txt); then echo yes; else echo no;fi
yes
if echo 'a string' > text.txt; then echo yes; else echo no;fi
yes
$?
在man 的PARAMETERS SET BY THE SHELL
zshparam
部分中,或者info zsh 'Parameters Set By The Shell'
您将看到,$?
是最后一个命令返回的退出状态。$(...)
在人身上
zshexpn
,或者info zsh 'Command Substitution'
你会看到:例如,表达式
$(echo 'a string')
将被替换为该命令 ( ) 的输出,a string<newline>
并删除尾随换行符,从而得到a string
. 但里面的命令$(echo 'a string' > test.txt)
不会向标准输出产生任何输出,因此该表达式的结果是一个空字符串。[[ ... ]]
zshmisc
在或 的手册页中info zsh 'Conditional Expressions'
,您将看到:[...]
现在举个例子
因此,在下一行中, 中命令的输出
$( ... )
是字符串,因此其自身a string<newline>
的扩展$(...)
将是a string
,这是一个非零长度的字符串,因此[[ ... ]]
计算将返回 true(0 退出状态)。但在下面的命令中,由于您进行了重定向,因此 的扩展
$( ... )
将是零长度字符串,并且[[ ... ]]
计算将返回 false(退出状态 1,是 0 以外的数字)。同样,下面命令的退出状态就是该
curl
命令的退出状态。will的联机帮助页
curl
说明了在什么条件下它返回非零(失败)退出状态。但在下一个示例中,退出状态将取决于
curl
命令是否有任何输出(成功)或没有任何输出(失败)。我将在此停止,但您可以继续阅读手册,例如man (或)的算术评估
(( ... ))
部分中的含义zshmisc
info zsh 'Arithmetic Evaluation'
我由此得出结论, using
[[ ... ]]
不适合评估成功的命令执行,除非以命令的输出结果产生非零字符串的方式理解成功的命令执行。为了在 zsh 脚本中进行验证,正确的方法是if command; then ...; [else ...;] fi
按照 muru 的评论所述使用)$?
随后检查其退出代码,和/或