如何制作“如果不是真实情况”?

时间:2012-05-11 13:51:37

标签: bash if-statement syntax boolean-expression

我想在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

6 个答案:

答案 0 :(得分:388)

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

grep如果找到搜索目标则返回true,如果找不到,则返回false

所以不要false == true

shell中的

if评估旨在非常灵活,并且很多时候不需要命令链(如您所写)。

此外,按原样查看代码,您对$( ... )形式的cmd替换的使用值得赞扬,但请考虑一下该过程的结果。试试echo $(cat /etc/passwd | grep "sysa")看看我的意思。您可以使用-c(计数)选项进一步使用grep,然后执行if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then哪个有效但是相当老派。

但是,您可以使用最新的shell功能(算术评估),如

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

这也为您提供了使用基于c-lang的比较运算符==,<,>,>=,<=,%以及其他一些运算符的好处。

在这种情况下,根据Orwellophile的评论,可以进一步减少算术评估,例如

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

OR

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

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

我希望这会有所帮助。

答案 1 :(得分:30)

我认为它可以简化为:

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; }

答案 2 :(得分:5)

  

我做错了什么?

$(...)包含,而不是退出状态,这就是这种方法错误的原因。但是,在这种特定情况下,它确实有效,因为将打印sysa,这使得测试语句成为现实。但是,if ! [ $(true) ]; then echo false; fi将始终打印false,因为true命令不会向stdout写入任何内容(即使退出代码为0)。这就是为什么需要将其改为if ! grep ...; then

另一种选择是cat /etc/passwd | grep "sysa" || echo error。编辑:正如Alex指出的那样,cat is useless heregrep "sysa" /etc/passwd || echo error

发现其他答案相当混乱,希望这有助于某人。

答案 3 :(得分:3)

这个

if [[ !  $(cat /etc/passwd | grep "sysa") ]]
Then echo " something"
exit 2
fi

答案 4 :(得分:1)

在支持它的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等内容的有效匹配。

要使grep解决方案正确,您需要正确解析/etc/passwd文件:

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

...或针对第一个:分隔字段的任何其他类似测试。

答案 5 :(得分:1)

以下是一个示例答案:

为了确保数据记录器处于联机状态,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

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

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

另外,仅供参考,请注意,由于cron作业以root运行,因此无需在sudo ping脚本中使用cron