如何做出“如果不是真实条件”?

我想在cat /etc/passwd | grep "sysa"不为真时执行echo命令。

我做错了什么?

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

试一试

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

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

因此NOT false (! false) == true

shell中的if计算被设计得非常灵活,并且很多时候不需要命令链(正如你所写的那样)。

同样,看看你的代码,你使用cmd-substitution的$( ... )形式是值得赞扬的,但考虑一下这个过程会产生什么。试试echo $(cat /etc/passwd | grep "sysa")看看我的意思。你可以进一步使用-c (count)选项来grep,然后执行if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then,这是可行的,但相当老派。

但是,您可以使用最新的shell特性(算术计算),例如

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

这也给了你使用基于c-lang的比较操作符的好处,==,<,>,>=,<=,%和其他一些。

在这种情况下,根据orwelloile的评论,算术计算可以进一步削减,比如

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

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

最后,还有一个名为Useless Use of Cat (UUOC)。:-)有些人会上蹿下跳地喊gothca!我只想说grep可以在它的cmd行上取一个文件名,那么为什么在你不需要的时候调用额外的进程和管道结构呢?: -)

我希望这能有所帮助。

我认为可以简化为:

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

我做错了什么?

$(...)保存的是价值,而不是退出状态,这就是为什么这种方法是错误的。然而,在这个特定的情况下,它确实工作,因为sysa将被打印出来,这使得测试语句成为现实。然而,if ! [ $(true) ]; then echo false; fi总是会打印false,因为true命令不会向标准输出写入任何内容(即使退出码为0)。这就是为什么它需要被改写为if ! grep ...; then

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

发现其他答案相当混乱,希望这能帮助到一些人。

在支持它的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

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

下面是一个例子:

为了确保数据记录器在线,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
#
< p >…你可以在蒙太奇中看到的每一个数据记录器 在http://www.SDsolarBlog.com/montage < / p >

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

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

另外,请注意,由于cron作业作为root运行,因此不需要在cron脚本中使用sudo ping

这一个

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

简单:

if ! examplecommand arg1 arg2 ...; then
#code block
fi

没有括号。