如何在bash中执行类似操作?

if "`command` returns any error";
then
    echo "Returned an error"
else
    echo "Proceed..."
fi


#1 楼


如果命令成功或失败,如何有条件地执行某些操作


这正是bash的if语句所执行的操作:

if command ; then
    echo "Command succeeded"
else
    echo "Command failed"
fi


从注释中添加信息:在这种情况下,您无需使用[ ... ]语法。 [本身就是一个命令,几乎等同于test。它可能是在if中使用的最常见的命令,这可能导致假设它是Shell语法的一部分。但是,如果要测试命令是否成功,请直接将命令本身与if一起使用,如上所示。

评论


请注意,分号很重要。

–索比昂·拉文·安德森(ThorbjørnRavn Andersen)
2011-10-17 7:37

或者,您也可以将其放在单独的一行中。

–l0b0
2011年10月17日9:00

@乔:我想你的意思是!命令;然后 ... ; fi。 [本身就是命令,在这种情况下不需要。

–基思·汤普森(Keith Thompson)
2012年1月13日上午10:19

@乔:我的方式还具有正确的优点。如果[!命令]不执行命令;它将命令视为字符串,并将其视为true,因为它的长度非零。 [是测试命令的同义词

–基思·汤普森(Keith Thompson)
2012年1月14日9:36



哎呀。没错

–乔
2012年1月14日上午10:09

#2 楼

对于要在shell命令有效的情况下发生的小事情,可以使用&&构造:

rm -rf somedir && trace_output "Removed the directory"


同样,对于要在shell发生的情况下发生的小事情命令失败,可以使用||

rm -rf somedir || exit_on_error "Failed to remove the directory"


或同时使用两个

rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"


这样做可能是不明智的这些结构可以带来很多好处,但有时它们可​​以使控制流程更加清晰。

评论


它们更短并且(至少在某些外壳中)更快。我不禁想起一个怪兽Ultrix安装脚本,它只是用我曾经试图破译的这些条件构造编写的...

– vonbrand
15年12月27日在22:15

#3 楼

检查$?的值,该值包含执行最新命令/功能的结果:

#!/bin/bash

echo "this will work"
RESULT=$?
if [ $RESULT -eq 0 ]; then
  echo success
else
  echo failed
fi

if [ $RESULT == 0 ]; then
  echo success 2
else
  echo failed 2
fi


评论


尽管从技术上讲是正确的(因此不保证投票不正确),但它并没有利用Bash的惯用法。我更喜欢基思·汤普森的答案。

– janmoesen
2011-10-17 11:30

这个习惯用法有很多好处-它保留了返回值。总的来说,我觉得这个功能更强大,虽然更冗长。它也更容易阅读。

–紫杉
2015年10月7日在21:16

什么是“ Bash的成语”?

– Nowowaker
16年6月27日在1:37

@Nowaker if的唯一目的就是这样做。 Bash中的流控制条件都检查$?幕后那就是他们的工作。在绝大多数情况下,没有必要明确检查其值,并且通常是初学者的反模式。

–tripleee
16年11月4日,12:34



我更喜欢这样做,以提高可读性。主要命令通常是一个很长的命令。将其放在“ if”语句中会降低可读性。

– Nikhil VJ
19-09-16的1:34

#4 楼

这对我有用:否则,将跳过command,并执行echo "OK"

评论


如果您想在失败时执行某项操作并保留退出代码(以显示在命令提示符中或在脚本中进行测试),则可以执行以下操作:command && echo“ OK” || c = $ ?;回声“ NOK”; $(退出$ c)

–山姆·哈斯勒
2014年6月24日15:57



@ Sam-Hasler:应该不是命令&&回显“ OK” || (c = $ ?; echo“ NOK”;(exit $ c))?

– jrw32982
2015年4月1日在18:24



另外,如果回显“ OK”部分本身可能失败,则更好:命令&&(回显“ OK”;退出0)|| (c = $ ?; echo“ NOK”;(exit $ c))

– jrw32982
2015年4月1日在18:34

@ jrw32982,很好,我使用了前一种结构,但没有使用过后者。

–山姆·哈斯勒
15年4月2日在16:11

真正的答案是在评论中,谢谢大家!

–约书亚·品特(Joshua Pinter)
17-10-24在20:13

#5 楼

应该注意,if...then...fi&& / ||类型的方法处理我们要测试的命令返回的退出状态(成功时为0);但是,如果命令失败或无法处理输入,则某些命令不会返回非零退出状态。这意味着通常的if&& / ||方法不适用于这些特定命令。例如,在Linux上,如果GNU file收到了不存在的文件作为参数,则它仍以0退出。 find找不到用户指定的文件。由stderr命令返回的代码,或者像stdin一样解析命令的输出。为此,可以使用file语句。

$ find . -name "not_existing_file"                                          
$ echo $?
0
$ file ./not_existing_file                                                  
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0


#6 楼

我最容易出错的是:


首先,获取值。假设您执行以下操作:

RR=$?

现在,不仅对于这种情况,而且您可能会遇到的其他情况,请考虑:

定义的变量:

$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi

答案:是

$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi

答案:否

未定义变量:

$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi

答案:否

$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi

答案:是

$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi

答案:是的

这可以防止各种错误。

您可能知道所有语法,但是这里有一些提示:


使用引号。避免将"blank"设为nothing
变量的新现代表示法是${variable}
在您的数字前添加一个串联的零也可以避免“根本没有数字”。
但是,请等一下,再加上一个零使数字变为base-8。对于value too great for base (error token is "08")以上的数字,您将得到类似以下错误:



7。这就是10#起作用的时候:

10#强制数字为base-10




#7 楼

您可以执行以下操作:

if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then
  echo "ping response succsess!!!"
fi


评论


可行,但令人费解。您正在子shell的子shell中运行ping,鉴于将ping作为命令运行,捕获了ping的输出。但是因为输出重定向到/ dev / null,所以它将始终是空字符串。因此,您在子Shell中什么也没有运行,这意味着将保留先前的退出状态(命令替换子Shell的状态,即ping)。显然,正确的方法是ping ...;然后在这里。

–StéphaneChazelas
2015年4月1日15:40



#8 楼

如本主题其他地方所述,原始问题基本上可以回答自己。这是说明if条件也可能嵌套的图示。

本示例使用if检查文件是否存在以及是否为常规文件。如果满足这些条件,则检查其大小是否大于0。

#!/bin/bash

echo "Which error log are you checking today? "
read answer

if [ -f /opt/logs/$answer*.errors ]
    then
        if [ -s /opt/logs/$answer*.errors ]
            then
                echo "Content is present in the $answer error log file."
            else
                echo "No errors are present in the $answer error log file."
        fi
    else
        echo "$answer does not have an error log at this time."
fi


评论


那是您的答案所做的,但是您的答案并未解决该问题。

– Jeff Schaller♦
15年12月24日在2:47

@JeffSchaller,谢谢您的来信。我编辑了帖子,以包含对该问题的引用。

–quartzinquartz
2015年12月27日21:00

#9 楼

#!/bin/bash

if command-1 ; then
   echo "command-1 succeeded and now running from this block command-2"
   command-2
else
   echo "command-1 failed and now running from this block command-3"
   command-3
fi


评论


这看起来很像现有的已接受答案。请归因于您正在重复使用的工作,或将自己的努力添加到答案中。

– Jeff Schaller♦
17年11月22日在16:36

#10 楼

这可以通过$?给出上次执行命令的状态来简单地完成。

所以它可能是


评论


Downvote:这简单地解释了一个较早的答案,该答案理所当然地受到批评,认为它是单反的。

–tripleee
16年11月4日,12:35