我希望在 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
!
不应该在括号内吗?即[ ! EXPR ]
尝试
if ! grep -q sysa /etc/passwd ; then
grep
如果找到搜索目标,则返回 true
,否则返回 false
。
所以不是 false
== true
。
if
shell 中的评估设计得非常灵活,而且很多时候不需要命令链(如您所写)。
此外,按原样查看您的代码,您使用 $( ... )
形式的 cmd-substitution 值得称赞,但请考虑该过程的结果。试试 echo $(cat /etc/passwd | grep "sysa")
看看我的意思。您可以通过使用 grep 的 -c
(计数)选项更进一步,然后执行 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
可以在其 cmd-line 上使用文件名,那么为什么在不需要时调用额外的进程和管道构造呢? ;-)
我希望这有帮助。
我认为可以简化为:
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; }
echo
末尾添加 1>&2
以在 stderr
上打印怎么样?
!: not found
'grep
时避免输出重定向。 -q
抑制输出。
这个
if [[ ! $(cat /etc/passwd | grep "sysa") ]]
Then echo " something"
exit 2
fi
我究竟做错了什么?
$(...)
保存 值,而不是退出状态,这就是这种方法错误的原因。但是,在这种特定情况下,它确实有效,因为 sysa
将被打印,这使得测试语句成真。但是,if ! [ $(true) ]; then echo false; fi
将始终打印 false
,因为 true
命令不会向 stdout 写入任何内容(即使退出代码为 0)。这就是为什么它需要改写为if ! grep ...; then
。
另一种选择是cat /etc/passwd | grep "sysa" || echo error
。编辑:正如亚历克斯指出的,cat is useless here:grep "sysa" /etc/passwd || echo error
。
发现其他答案相当混乱,希望这对某人有所帮助。
这是一个示例的答案:
为了确保数据记录器在线,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
(条件只需要 ping
命令的 exit status
)
另外仅供参考,请注意,由于 cron
作业作为 root
运行,因此无需在 cron
脚本中使用 sudo ping
。
简单地:
if ! examplecommand arg1 arg2 ...; then
#code block
fi
没有任何括号。
在支持它的 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
等内容的有效匹配。
要使 grep
解决方案正确,您需要正确解析 /etc/passwd
文件:
if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
# found
else
# not found
fi
... 或针对第一个以 :
分隔的字段的任何其他类似测试。
bash
执行。
不定期副业成功案例分享
grep "^$user:" /etc/passwd
将是顺便搜索 /etc/passwd 的更正确方法 -grep -v
where -v如果您想避免 || 的混乱,则反转搜索(( $( cat file | grep regex | wc -l ) ? 0 : 1 ))