否定bash脚本中的条件

Don*_*nai 141 linux bash if-statement negate

我是bash的新手,我一直试图否定以下命令:

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -eq 0 ]]; then
        echo "Sorry you are Offline"
        exit 1
Run Code Online (Sandbox Code Playgroud)

如果我连接到互联网,这个if条件返回true.我希望它以相反的方式发生,但放在!任何地方似乎都不起作用.

Cyr*_*rus 193

你可以选择:

if [[ $? -ne 0 ]]; then       # -ne: not equal

if ! [[ $? -eq 0 ]]; then     # -eq: equal

if [[ ! $? -eq 0 ]]; then
Run Code Online (Sandbox Code Playgroud)

! 分别反转以下表达式的返回值.

  • 是必要的双括号?这是为什么? (8认同)
  • @AlexanderMills:有几种方法可以做到这一点。使用双括号或单括号或使用 `test` 命令:`if test $? -ne 0; 那么` (3认同)
  • 这个答案是不必要的冗长。如果if期望的语句为0或1,那么您可以使用命令本身并将其反转:`if!wget ...; 然后 ...; fi (2认同)

小智 75

更好

if ! wget -q --spider --tries=10 --timeout=20 google.com
then
  echo 'Sorry you are Offline'
  exit 1
fi
Run Code Online (Sandbox Code Playgroud)

  • 重要提示:在“!”和以下命令之间保留一个空格,否则您将进行历史扩展。https://unix.stackexchange.com/questions/3747/understanding-the-exclamation-mark-in-bash (2认同)
  • 史蒂文为什么你只有 1 声望? (2认同)
  • 看起来史蒂文已被禁止 - 如果你查看他的个人资料,会发现他被停职至 2022 年秋季 (2认同)

dav*_*igh 8

您可以使用不等比较-ne代替-eq

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -ne 0 ]]; then
    echo "Sorry you are Offline"
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)


Col*_*ney 8

如果你感到懒惰,这里有一个简洁的方法,在操作后使用||(或)和&&(和)处理条件:

wget -q --tries=10 --timeout=20 --spider http://google.com || \
{ echo "Sorry you are Offline" && exit 1; }
Run Code Online (Sandbox Code Playgroud)

  • 在现实生活中的脚本中,您应该将echo命令之后的`&&`更改为`;`.原因是如果输出被重定向到整个磁盘上的文件,`echo`将返回失败并且`exit`将永远不会触发.这可能不是您想要的行为. (8认同)

Ben*_* W. 5

由于您要比较数字,因此可以使用算术表达式,它可以更简单地处理参数和比较:

wget -q --tries=10 --timeout=20 --spider http://google.com
if (( $? != 0 )); then
    echo "Sorry you are Offline"
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)

请注意-ne,您可以直接使用!=. 在算术上下文中,我们甚至不必预先添加$参数,即

var_a=1
var_b=2
(( var_a < var_b )) && echo "a is smaller"
Run Code Online (Sandbox Code Playgroud)

工作得很好。但这不适用于$?特殊参数。

此外,由于(( ... ))将非零值评估为 true,即非零值的返回状态为 0,否则返回状态为 1,因此我们可以缩短为

if (( $? )); then
Run Code Online (Sandbox Code Playgroud)

但这可能会让更多的人感到困惑,而不是节省的击键次数的价值。

该构造在 Bash 中可用,但POSIX shell 规范(( ... ))不需要(尽管提到了可能的扩展)。

$?话虽如此,我认为最好完全避免,就像科尔的回答史蒂文的回答一样。