我想在bash脚本中编写一段代码,用于检查程序是否已在运行。 我有以下内容,以搜索栏是否正在运行
foo=`ps -ef | grep bar | grep -v grep`
在
grep -v grep
部分是为了确保在ps结果中不考虑“grep bar”
当bar未运行时,foo正确为空。但我的问题在于脚本已经
set -e
是一个标志,如果某个命令返回错误,则终止脚本。 事实证明,当bar未运行时,“grep -v grep”与任何内容都不匹配,grep会返回错误。我尝试使用-q或-s但无济于事。
有没有解决方法? THX
答案 0 :(得分:61)
不确定
ps -ef | grep bar | { grep -v grep || true; }
甚至:
ps -ef | grep bar | grep -v grep | cat
答案 1 :(得分:15)
避免grep -v grep
的好方法是:
ps -ef | grep '[b]ar'
该正则表达式仅匹配字符串“bar”。但是在ps
输出中,字符串“bar”不会出现在grep进程中。
在我了解pgrep
之前的几天,我写了这个函数来自动执行上面的命令:
psg () {
local -a patterns=()
(( $# == 0 )) && set -- $USER
for arg do
patterns+=("-e" "[${arg:0:1}]${arg:1}")
done
ps -ef | grep "${patterns[@]}"
}
然后,
psg foo bar
变成
ps -ef | grep -e '[f]oo' -e '[b]ar'
答案 2 :(得分:10)
为什么要求ps
提供-ef
的大量输出,如果你只是要扔掉99%的输出? ps
尤其是GNU版本是瑞士军刀,功能强大。试试这个:
ps -C bar -o pid= 1>/dev/null
我在这里指定-o pid=
只是因为,但事实上它是毫无意义的,因为我们无论如何都扔掉了所有的stdout。但是,如果您想知道实际运行的PID,那将非常有用。
ps
无法匹配任何内容, -C
将自动返回非零存在状态,如果匹配则为零。所以你可以简单地说这个
ps -C bar 1>/dev/null && echo bar running || echo bar not running
或者
if ps -C bar 1>/dev/null ; then
echo bar running
else
echo bar not running
fi
这不是更简单吗?不需要grep,不需要两次甚至一次。
答案 3 :(得分:7)
写
ps -ef | grep bar | { grep -v grep || test $? = 1; }
如果您使用 set -e
。
如果您使用bash的 pipefail
选项(set -o pipefail
),请务必将异常处理(||test
)应用于每个grep
管道
ps -ef | { grep bar || test $? = 1; } | { grep -v grep || test $? = 1; }
在 shell脚本中,我建议您使用“catch-1-grep”(c1grep)实用程序函数:
c1grep() { grep "$@" || test $? = 1; }
grep
的退出状态为0,1或2:[1]
0
表示已选择一行1
表示未选择任何行2
表示发生了错误 grep
如果被信号中断(例如,130
用于SIGINT),也可以返回其他代码。
由于我们只想忽略退出状态1
,因此我们使用test
来取消特定的退出状态。
grep
返回0
,则test
未运行。grep
返回1
,则会运行test
并返回0
。grep
返回任何其他值,则会运行test
并返回1
。在最后一种情况下,由于set -e
或set -o pipefail
,脚本会立即退出。但是,如果您根本不关心grep
错误,您当然可以写
ps -ef | grep bar | { grep -v grep || true; }
根据Sean的建议。
在shell脚本中,如果你经常使用grep
,我建议你定义一个效用函数:
# "catch exit status 1" grep wrapper
c1grep() { grep "$@" || test $? = 1; }
这样你的烟斗就会变短了。再简单,不会丢失set -e
和set -o pipefail
的功能:
ps -ef | c1grep bar | c1grep -v grep
供参考:
c1grep
强调它只是捕捉退出状态1
,没有别的。grep
而不是grep() { env grep "$@" ...; }
),但我更喜欢一个不那么混乱且更明确的名称c1grep
。 [1] grep
联页>
答案 4 :(得分:1)
foo=`ps -ef | grep bar | grep -v grep` || true
答案 5 :(得分:1)
尝试这样做:
ps auxw | grep -v grep |猫
cat总是返回0并忽略grep的退出代码