bash if 语句行为问题

bash if 语句行为问题

我写了下面这段 bash 脚本。

if [ $(tmux has -t junk) ]
then
echo zero
else
echo one
fi

无论会话是否存在,它总是返回 1。我通过执行 tmux 语句然后运行 ​​$? 来检查命令行。 。它的行为符合预期,如果会话存在则为零,如果会话不存在则为 1 为什么不是 if 语句的行为方式不同。我尝试更改 if 语句,如下所示

tmux has -t junk
if [ $? -eq 0 ]
then
echo zero
else
echo one
fi

上面的事情有效。那么第一个语句块有什么问题呢?

答案1

如前所述,if [ $(tmux has -t junk) ]expand to 的if [ ]值为 false。

你可以使用:

if tmux has -t junk; then
    echo OK
else
    echo ERR
fi

或者如果你想要更短的:

tmux has -t junk || echo ERR

或者

tmux has -t junk && echo OK || echo ERR

如果更合适,您也可以否定它,如下所示:

! tmux has -t junk || echo OK
! tmux has -t junk && echo ERR || echo OK
etc.

编辑:

另外,如果命令产生输出,您可能希望将该输出重定向到黑洞,如下/dev/null所示:

 if my_cmd >/dev/null; then echo OK else; echo ERR; fi

如果命令产生文本错误,您可能还想通过以下方式重定向标准错误:

 if my_cmd >/dev/null 2>&1; then echo OK else; echo ERR; fi

接下来的内容,您可能已经很了解,但添加它是为了更加完整。

如前所述:$?是获取程序返回值的唯一方法。

有些程序的返回值不同,并且可能具有相当明确的含义。

所以例如:

mycmd
ecode=$?

case "$ecode" in
0) echo "Success";;
1) echo "Operation not permitted";;
2) echo "No such file or directory";;
esac

通过这一点,可以对特定错误采取适当的操作。

如果你安装了MySQL,你可以这样做错误:

for i in {0..50}; do perror $i; done
# And
for i in {1000..1050}; do perror $i; done

来感受一下。

也可以看看这个答案与操作系统特定错误相关,也链接到 Open Groups 文档错误编号错误号

或者看一下SQLite和它的扩展的

答案2

当您使用:

if [ $(tmux has -t junk) ]

这会检查命令的输出tmux has -t junk,但不检查返回值。

因此,由于它总是像第一种情况一样打印一个,这意味着该tmux has -t junk命令不会在标准输出上打印任何内容。

所以在第一种情况下,

if [ $(tmux has -t junk) ] 

被评价为

if [ ]

相关内容