如何使“如果不是真实的条件”?
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
这会引起一些有趣的事情,比如cara
和enoc
等,尽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
。