如何使“如果不是真实的条件”?

cat /etc/passwd | grep "sysa"时,我想要执行echo命令 cat /etc/passwd | grep "sysa"不正确。

我究竟做错了什么?

 if ! [ $(cat /etc/passwd | grep "sysa") ]; then echo "ERROR - The user sysa could not be looked up" exit 2 fi 

尝试

 if ! grep -q sysa /etc/passwd ; then 

如果findsearch目标,则grep返回true否则返回false

所以不是false == true

if贝壳评估的devise非常灵活,并且很多时候不需要命令链(就像你写的那样)。

此外,按照原样查看代码,使用$( ... )forms的cmdreplace是值得赞扬的,但要考虑过程中出现的内容。 试试echo $(cat /etc/passwd | grep "sysa")来查看我的意思。 你可以进一步通过使用-c (count)选项来grep,然后做, if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then哪个有用,但是比较老派。

但是,你可以使用最新的shellfunction(算术评估)

 if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...` 

这也给你使用基于c-lang的比较运算符的好处, ==,<,>,>=,<=,%和其他几个。

在这种情况下,根据Orwellophile的评论,算术评估可以进一步缩减,就像

 if ! (( $(grep -c "sysa" /etc/passwd) )) ; then .... 

要么

 if (( ! $(grep -c "sysa" /etc/passwd) )) ; then .... 

最后还有一个称为“ Useless Use of Cat (UUOC)奖项 。 :-)有些人会跳起来,哭泣gothca! 我只是说, grep可以在其cmd行上取一个文件名,那么为什么在不需要的时候调用额外的进程和pipe道结构呢? 😉

我希望这有帮助。

我认为可以简化为:

 grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up" exit 2 } 

或者在一个命令行中

$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }

在支持它的Unix系统(不像macOS似乎):

 if getent passwd "$username" >/dev/null; then printf 'User %s exists\n' "$username" else printf 'User %s does not exist\n' "$username" fi 

这样做的好处是可以查询任何可能正在使用的目录服务(YP / NIS或LDAP等)和本地密码数据库文件。


grep -q "$username" /etc/passwd是,如果没有这样的用户,它会给出错误的肯定,但是其他的匹配模式。 如果文件中的其他地方存在部分或完全匹配,则可能发生这种情况。

例如,在我的passwd文件中,有一句话说

 build:*:21:21:base and xenocara build:/var/empty:/bin/ksh 

这会引起一些有趣的事情,比如caraenoc等,尽pipe我的系统中没有这样的用户。

为了使grep解决scheme正确,您需要正确parsing/etc/passwd文件:

 if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then # found else # not found fi 

或者对第一个: -delimited字段进行任何其他类似的testing。

我究竟做错了什么?

$(...)保存 ,而不是退出状态,这就是为什么这种方法是错误的。 然而,在这个特定的情况下,它确实工作,因为sysa将被打印,这使得testing语句成为现实。 但是, if ! [ $(true) ]; then echo false; fi if ! [ $(true) ]; then echo false; fi if ! [ $(true) ]; then echo false; fi会总是打印false因为true命令不会写任何东西到标准输出(即使但退出代码为0)。 这就是为什么它需要重新考虑, if ! grep ...; then if ! grep ...; then if ! grep ...; then

另一种方法是cat /etc/passwd | grep "sysa" || echo error cat /etc/passwd | grep "sysa" || echo error cat /etc/passwd | grep "sysa" || echo error 。 像Alex指出的那样编辑, cat在这里是没用的 : grep "sysa" /etc/passwd || echo error grep "sysa" /etc/passwd || echo error

发现其他答案相当混乱,希望这可以帮助别人。

下面是一个例子的答案:

为了确保数据logging器在线, cron脚本每15分钟运行一次,如下所示:

 #!/bin/bash # if ! ping -c 1 SOLAR &>/dev/null then echo "SUBJECT: SOLAR is not responding to ping" | ssmtp abc@def.com echo "SOLAR is not responding to ping" | ssmtp 4151112222@txt.att.com else echo "SOLAR is up" fi # if ! ping -c 1 OUTSIDE &>/dev/null then echo "SUBJECT: OUTSIDE is not responding to ping" | ssmtp abc@def.com echo "OUTSIDE is not responding to ping" | ssmtp 4151112222@txt.att.com else echo "OUTSIDE is up" fi # 

…等等,您可以在http://www.SDsolarBlog.com/montage上的蒙太奇中看到每个数据logging器;


仅供参考,使用&>/dev/null将命令的所有输出(包括错误)redirect到/dev/null

(条件只需要ping命令的exit status

另外FYI,请注意,因为cron作业以root身份运行,所以不需要在cron脚本中使用sudo ping