我的系统上有一个进程,它因崩溃而臭名昭著,并且是一种关键任务,我的网络管理员。无论如何,我需要编写一个循环来测试它是否正在运行,如果没有运行则启动它。这是我到目前为止所想出的:
#!/bin/bash
while [ true ]; do
if [ -z $(ps aux | grep "[n]m-applet") ]; then
echo "Bugger died, resurrecting..."
nm-applet >/dev/null 2>/dev/null &
disown $!
fi
sleep 3
done
不幸的是,这并不能完全解决问题,因为即使没有必要,它似乎也会启动该过程,并且在第一次运行后,我得到以下错误输出:
line 4: [: too many arguments
我在这里做错了什么?
答案1
尝试$(...)
用双引号括起来:
if [ -z "$(ps aux | grep '[n]m-applet')" ]; then
但您可能想尝试使用pgrep
orps axo cmd | grep '[n]m-applet'
代替。
答案2
该错误来自于向 -z 提供多个参数。它是一个一元运算符,如果展开$()
为其中包含 $IFS 的内容,它将看到多个参数。要解决这个问题,您可以在它周围加上引号,如下所示[ -z "$(ps...)" ]
:
在这种情况下,您实际上不需要 test ( []
),因为如果 grep 没有找到任何内容,它将返回非零值。你可以做:
if ps aux | grep '[n]m-applet' > /dev/null; then
您可能想看看您计划部署的系统是否具有pgrep
.它是为了寻找与模式匹配的进程而设计的。
另外,您可能不希望脚本将 nm-applet 设置为后台。这样,脚本将阻塞,直到 nm-applet 终止。
最后,您可能想看看莫尼特,它是为了执行您的脚本所做的事情而设计的。
答案3
我不确定你的理由while [ true ]; do
,我其次阿尔切格的建议使用pgrep
.
#!/bin/bash
while true; do
if ! pgrep nmapplet &>/dev/null; then
echo "Bugger died, resurrecting..."
nm-applet &>/dev/null
disown $!
fi
sleep 3
done