我有一个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,所以应该没问题吗?
脚本的路径名与最终grep
匹配,因此它找到自己并满意。
这没有以交互方式发生的原因是您没有使用完整路径运行它。
这是一个非常常见的常见问题解答。
切向地,您的脚本包含两个非常常见的反模式。你正在糟糕地重塑pidof
,你正在明确地检查$?
。除非您特别要求退出代码为 1,否则您应该只执行
if ! ps -ef | grep -q '[o]penvpn'; then
因为if
的目的是运行命令并检查其退出代码;并且还要注意使用与自身不匹配的正则表达式的技巧。但是使用 pidof
还可以让您轻松检查二进制可执行文件的文件名,而不是其路径。
我终于明白为什么脚本不起作用了。由于它位于/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
这工作得很好。谢谢大家。