ChatGPT解决这个技术问题 Extra ChatGPT

否定 bash 脚本中的 if 条件

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

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

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

你把它放在哪里了? if ! [[ ... 有效
你也可以这样使用它:wget your_xxxx_params || (回声“哦哦”&&退出1)
> 调用子shell 只是为了输出错误

C
Cyrus

您可以选择:

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

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

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

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


双括号是必要的吗?这是为什么?
@AlexanderMills:有几种方法可以做到这一点。使用双括号或单括号或使用 test 命令:if test $? -ne 0; then
这个答案是不必要的冗长。 if 需要一个 0 或 1 的语句,因此您可以使用命令本身并将其反转:if ! wget ...; then ...; fi
Z
Zombo

更好的

if ! wget -q --spider --tries=10 --timeout=20 google.com
then
  echo 'Sorry you are Offline'
  exit 1
fi

重要提示:在 ! 和以下命令之间保留一个空格,否则您将进行历史扩展。 unix.stackexchange.com/questions/3747/…
史蒂文你为什么只有1个声望?
看起来史蒂文已被禁止 - 如果你查看他的个人资料,它会说他被停职到 2022 年秋季😳
C
Cole Tierney

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

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

在实际脚本中,您应该将 echo 命令后的 && 更改为 ;。这样做的原因是,如果输出被重定向到一个完整磁盘上的文件,echo 将返回失败,exit 将永远不会触发。这可能不是您想要的行为。
或者您可以使用 set -e,失败的 echo 将退出脚本
B
Benjamin W.

由于您在比较数字,因此您可以使用 arithmetic expression,这样可以更简单地处理参数和比较:

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"

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

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

if (( $? )); then

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

(( ... )) 构造在 Bash 中可用,但 POSIX shell specification 不需要(但作为可能的扩展提及)。

综上所述,在我看来,最好完全避免使用 $?,如 Cole's answerSteven's answer


@DavidC.Rankin 哦,我没找到!所以它被称为扩展,但不是必需的。我会修改。
是的,那个总是让我也喜欢。尽管:),它确实让 shell 中的生活更轻松
V
Victor Schröder

您可以使用不等比较 -ne 而不是 -eq

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