否定bash脚本中的条件


162

我是bash的新手,但我一直想尝试取消以下命令:

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

如果我已连接到互联网,则此条件返回true。我希望它以相反的方式发生,但是放在!任何地方似乎都行不通。


3
你放哪去了 if ! [[ ...的作品
另一个家伙

1
您也可以通过以下方式使用它:wget your_xxxx_params || (echo“ oh oh” && exit 1)
AKS

2
>调用subshel​​l只是为了输出错误
tijagi 2014年

Answers:


227

您可以选择:

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

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

if [[ ! $? -eq 0 ]]; then

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


9
是否需要双括号?这是为什么?
亚历山大·米尔斯

1
@AlexanderMills:有几种方法可以做到这一点。带双括号或单括号或带有test命令:if test $? -ne 0; then
Cyrus

4
这个答案是不必要的冗长。if期望语句为0或1,因此您可以使用命令本身并将其取反:if ! wget ...; then ...; fi
Nils Magnus,


8

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

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

8
在现实生活中的脚本中,应将&&after echo命令更改为;。这样做的原因是,如果将输出重定向到完整磁盘上的文件,则echowill返回失败,并且exit将永远不会触发。这可能不是您想要的行为。
21:06时

否则您可以使用,set -e并且失败echo将仍然退出脚本
Jakub Bochenski

4

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

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

注意如何代替-ne,您可以使用!=。在算术上下文中,我们甚至不必$在参数之前,例如,

var_a=1
var_b=2
(( var_a < var_b )) && echo "a is smaller"

工作完美。但是,这不适用于$?特殊参数。

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

if (( $? )); then

但这可能会使更多的人迷惑,所节省的击键值不值。

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

$?综上所述,在我看来,最好完全避免像科尔的回答史蒂文的回答那样



@ DavidC.Rankin哦,我没有找到!因此,它被称为扩展,但不是必需的。我会修正。
本杰明·W.

1
是的,那个人总是也吸引我。但这确实使外壳的生活变得更轻松:)
David C. Rankin

4

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

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -ne 0 ]]; then
    echo "Sorry you are Offline"
    exit 1
fi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.