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


评论

应该!不在括号内吗?即[! EXPR]

@ acraig5075这两种方法都是有效的,但是此语句中根本不需要测试命令(即括号)。

#1 楼

请尝试

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


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

false在shell中进行评估的目的是非常灵活,并且很多时候不需要命令链(如您所写)。

同样,以原样看待您的代码,您对true形式的cmd替换的使用也应受到赞赏,但请考虑一下该过程中会发生什么。尝试if明白我的意思。您可以使用$( ... )(计数)选项对grep进行进一步处理,然后执行echo $(cat /etc/passwd | grep "sysa"),尽管可行,但它相当老派。 br />
if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`


,这也使您受益于使用基于c语言的比较运算符-c以及其他一些运算符。 ,根据Orwellophile的评论,算术评估甚至可以进一步削减,例如

if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....
br />最后,有一个名为if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; then的奖项。 :-)有些人会跳来跳去,呼喊哥特卡!我只是说==,<,>,>=,<=,%可以在其cmd行上取一个文件名,所以为什么在不需要时调用额外的进程和管道构造呢? ;-)

希望对您有所帮助。

评论


从我的答案到更困难的(问题),这确实是很愚蠢的[stackoverflow.com/a/30400327/912236] grep“ ^ $ user:” / etc / passwd是搜索/ etc / passwd的更正确方法顺便说一句– grep -v如果您想避免||混乱,-v会反转搜索。

–嗜尿菌
2015年6月1日在16:59



是的,嗯,最有效地解决了一个问题,然后回答了特定的问题。我试图回答具体问题。感谢您的想法。祝你们好运。

–脱壳机
2015年6月1日于17:05

不选择您的答案,非常喜欢。我只是通过我会在用户名上进行适当范围的检查,否则,如果OP确实确实在“ sys”或类似名称上进行搜索,他会感到非常惊讶。再上一条路? (($(cat文件| grep regex | wc -l)?0:1))

–嗜尿菌
2015年6月1日17:12



大!由于某种原因,reqular“!grep -qs ...”无法与/ proc / mounts一起使用,并试图找出是否有定期删除的USB磁盘安装在Raspbian 4.9内核上。这一位做得很好!

– DocWeird
19年11月27日在12:51

#2 楼

我认为可以将其简化为:

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

评论


很好,但是我更喜欢Shellter先生的回答,因为它是“自我记录”的,更容易理解程序员的意图。

–0zkr PM
2014-09-18 22:03

我喜欢这个版本。在回显末尾添加1>&2以在stderr上打印该怎么办?

–朱利安
15年11月26日在11:32



@ 0zkrPM但是shellster版本在Bourne shell中不起作用。您将获得!:找不到

–天花板
16-3-14在13:29

像这样使用'grep时,避免输出重定向。 -q禁止输出。

–tbc0
16年7月26日在22:04

#3 楼


我在做什么错?


$(...)保存值,而不是退出状态,这就是为什么这种方法是错误的。但是,在这种特定情况下,它确实可以工作,因为将打印sysa,这使测试语句成为现实。但是,if ! [ $(true) ]; then echo false; fi将始终打印false,因为true命令不会向stdout写入任何内容(即使退出代码为0)。这就是为什么需要将其改写为if ! grep ...; then的原因。
另一个选择是cat /etc/passwd | grep "sysa" || echo error。编辑:正如亚历克斯所指出的,猫在这里是无用的:grep "sysa" /etc/passwd || echo error

#4 楼

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


评论


欢迎使用堆栈溢出。不鼓励在堆栈溢出上使用仅代码的答案,因为它们没有解释它如何解决问题。请编辑您的答案,以解释该代码的作用,以及该代码在该问题已获得其他认可的答案的基础上的改进,从而对遇到类似问题的其他用户很有用。

– FluffyKitten
20/09/17'8:32

#5 楼

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

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

/etc/passwd分隔字段中的第一个进行任何其他类似测试。

评论


@SDsolar在这种情况下,您的代码可能不会被bash执行。

–库萨兰达
17年11月8日在10:35

#6 楼

以下是示例答案:

为了确保数据记录器处于联机状态,每15分钟运行一次cron脚本,如下所示:

#!/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
上的剪辑画面中看到每个数据记录器FYI使用&>/dev/null将命令的所有输出(包括错误)重定向到/dev/null

(条件仅要求exit status命令的pingcron作业以root运行,因此无需在sudo ping脚本中使用cron