Linux 美元的使用?在if语句条件表达式中

Linux 美元的使用?在if语句条件表达式中,linux,bash,Linux,Bash,以下面的bash脚本为例: #!/bin/bash ls /sdfg if [ $? -gt 0 ] then echo "Command failed: $?" else echo "Command succeeded: $?" fi 输出将是: ls: cannot access /sdfg: No such file or directory Command failed: 0 失败的ls命令实际上返回2,if语句捕捉到了这一点,而echos命令失败

以下面的bash脚本为例:

#!/bin/bash

ls /sdfg

if [ $? -gt 0 ]
then
        echo "Command failed: $?"
else
        echo "Command succeeded: $?"
fi
输出将是:

ls: cannot access /sdfg: No such file or directory
Command failed: 0
失败的ls命令实际上返回2,if语句捕捉到了这一点,而echos命令失败,但是为什么$?更新到零?看起来if/then行被视为一个新命令。

[实际上是一个二进制,而不仅仅是一些标点符号:

$ ls -l /usr/bin/[
-rwxr-xr-x 1 root root 51920 Feb 18 07:37 /usr/bin/[
$ /usr/bin/[ --version
[ (GNU coreutils) 8.25
Copyright (C) 2016 Free Software Foundation, Inc.
在某些系统上,可能需要进行符号链接测试

所以这里

if [ $? -gt 0 ]
$?是ls调用的结果,但在这里

    echo "Command failed: $?"
$?是执行[上一行]的结果

如果要多次从命令测试$?,则必须将其填充到临时变量中:

ls blahblah
temp=$?
if [ $temp ... ]
if [ $temp ... ]
[实际上是二进制,而不仅仅是一些标点符号:

$ ls -l /usr/bin/[
-rwxr-xr-x 1 root root 51920 Feb 18 07:37 /usr/bin/[
$ /usr/bin/[ --version
[ (GNU coreutils) 8.25
Copyright (C) 2016 Free Software Foundation, Inc.
在某些系统上,可能需要进行符号链接测试

所以这里

if [ $? -gt 0 ]
$?是ls调用的结果,但在这里

    echo "Command failed: $?"
$?是执行[上一行]的结果

如果要多次从命令测试$?,则必须将其填充到临时变量中:

ls blahblah
temp=$?
if [ $temp ... ]
if [ $temp ... ]

无论如何,您应该很少需要显式地检查$?,因为这样做是if和其他条件内置(如while)的目的

if ls /sdfg; then
    echo "Command succeeded: $?"
else
    echo "Command failed: $?"
fi

请注意,失败案例现在是else分支。如果您不特别关心保留失败退出代码,可以使用If!ls…并将成功分支保留在else中,但您的问题似乎是专门关于保留它,而使用!进行否定则不行。

无论如何,您应该很少需要显式检查$,因为这样做是if和while等其他条件内置函数的目的

if ls /sdfg; then
    echo "Command succeeded: $?"
else
    echo "Command failed: $?"
fi
请注意,失败案例现在是else分支。如果您不特别关心保留失败退出代码,可以使用If!ls…并将成功分支保留在else中,但您的问题似乎是专门关于保留它,而使用!进行否定则不行。

在命令后立即收集返回值如果要重复使用,则正在进行测试:

#!/bin/bash

# best-practice: collect *on the same line*, so any logging added in the future doesn't
# ...change your exit status.
ls /sdfg; retval=$?

if [ $retval -gt 0 ]; then
        echo "Command failed: $retval" # 
else
        echo "Command succeeded: $retval"
fi
但是,最佳做法是直接操作命令的退出状态,而无需参考$?:

如果要重用命令,请在测试命令后立即收集返回值:

#!/bin/bash

# best-practice: collect *on the same line*, so any logging added in the future doesn't
# ...change your exit status.
ls /sdfg; retval=$?

if [ $retval -gt 0 ]; then
        echo "Command failed: $retval" # 
else
        echo "Command succeeded: $retval"
fi
但是,最佳做法是直接操作命令的退出状态,而无需参考$?:


[是一个名为test的命令]是一个名为testOK的命令,很好。感谢您的详细解释。如果您避免运行[这通常是一种反模式],则不需要使用temp变量。好的,很好。感谢您的详细解释。如果您避免运行[这通常是一种反模式],则不需要使用temp变量。