402

我希望在不正确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
4

7 回答 7

559

尝试

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

greptrue如果找到搜索目标,则返回,否则返回false

所以不是false== true

ifshell 中的评估被设计为非常灵活,并且很多时候不需要命令链(如您所写)。

此外,按原样查看您的代码,您$( ... )对 cmd-substitution 形式的使用值得称赞,但请考虑该过程的结果。试着echo $(cat /etc/passwd | grep "sysa")看看我的意思。您可以通过使用-cgrep 的 (count) 选项来进一步实现这一点,然后执行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 ....

或者

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

最后,还有一个奖项,叫做Useless Use of Cat (UUOC). :-) 有些人会跳上跳下哭哥特卡!我只是说它grep可以在它的命令行上取一个文件名,那么为什么在你不需要的时候调用额外的进程和管道构造呢?;-)

我希望这有帮助。

于 2012-05-11T13:54:59.420 回答
38

我认为可以简化为:

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

于 2012-05-13T15:05:26.347 回答
18

这个

if [[ !  $(cat /etc/passwd | grep "sysa") ]]
Then echo " something"
exit 2
fi
于 2020-09-17T02:46:38.373 回答
10

What am I doing wrong?

$(...) holds the value, not the exit status, that is why this approach is wrong. However, in this specific case, it does indeed work because sysa will be printed which makes the test statement come true. However, if ! [ $(true) ]; then echo false; fi would always print false because the true command does not write anything to stdout (even though the exit code is 0). That is why it needs to be rephrased to if ! grep ...; then.

An alternative would be cat /etc/passwd | grep "sysa" || echo error. Edit: As Alex pointed out, cat is useless here: grep "sysa" /etc/passwd || echo error.

Found the other answers rather confusing, hope this helps someone.

于 2017-09-02T18:38:16.767 回答
3

这是一个示例的答案:

为了确保数据记录器在线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 pingcron脚本中使用。

于 2017-11-08T16:07:29.367 回答
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

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

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

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

于 2017-09-02T18:46:13.160 回答
0

simply:

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

without any brackets.

于 2022-02-01T13:23:24.617 回答