我有一个Raspberry Pi通过openvpn连接到VPN。连接会定期丢失,因此我使用以下脚本:
#!/bin/bash
ps -ef | grep -v grep | grep openvpn
if [ $? -eq 1 ] ; then
/sbin/shutdown -r now
fi
我将它添加到crontab(使用sudo crontab -e
),我希望脚本每5分钟执行一次:
*/5 * * * * /etc/openvpn/check.sh
该脚本不起作用,但似乎仍然每五分钟执行一次:
tail /var/log/syslog | grep CRON
给出:
Mar 16 21:15:01 raspberrypi CRON[11113]: (root) CMD (/etc/openvpn/check.sh)
...
此外,当我使用sudo ./check.sh
手动运行脚本时,Pi会重新启动它。
我真的不明白这里发生了什么?
修改:
正如所建议的那样,我添加了完整的路径名,然后从重启Pi再到openvpn:
#!/bin/bash
if ! /bin/ps -ef | /bin/grep '[o]penvpn'; then
cd /etc/openvpn/
/usr/sbin/openvpn --config /etc/openvpn/config.ovpn
fi
脚本仍然不起作用,虽然我自己执行它时运行正常。脚本的权限是755,所以应该没问题?
答案 0 :(得分:3)
脚本的路径名与最终的grep
匹配,因此它找到了自己,并且感到满意。
这不是以交互方式发生的原因是你没有以完整的路径运行它。
这是一个非常常见的常见问题解答。
切向地,您的脚本包含两个非常常见的反模式。你正在重新发明pidof
,你正在明确地检查$?
。除非您明确要求退出代码为1,否则您应该只是执行
if ! ps -ef | grep -q '[o]penvpn'; then
因为if
的目的是运行命令并检查其退出代码;并注意使用与自身不匹配的正则表达式的技巧。但是使用pidof
还可以让您轻松检查二进制可执行文件的文件名,而不是其路径。
答案 1 :(得分:0)
我终于明白为什么剧本不起作用。由于它位于/etc/openvpn
下,因为脚本正在执行,因此if ! ps -ef | grep -q '[o]penvpn'
条件不会返回true
。当我将crontab行更改为:
*/5 * * * * /etc/openvpn/check.sh >/home/pi/output 2>/home/pi/erroutput
output
文件显示正在运行/etc/openvpn/check.sh
脚本。
现在的脚本是:
#!/bin/bash
if ! pidof openvpn; then
cd /etc/openvpn/
/usr/sbin/openvpn --config /etc/openvpn/config.ovpn
fi
这很好用。谢谢大家。