有两种常见的情况我想处理:
>我有一个应该永远运行的脚本。如果它死了(或重新启动),重新启动它。不要让有一个副本同时运行(检测副本是否已经运行,在这种情况下不启动它)。
>我有一个简单的脚本或命令行命令,我想永远重复执行(运行之间有一个短暂的停顿)。同样,不允许脚本的两个副本一次运行。
当然,在情况2中对脚本写一个“while(true)”循环然后对情况1应用一个@R_301_463@案是微不足道的,但是一个更一般的@R_301_463@案将直接解决情况2,因为这适用于案例1中的脚本(你可能只是想要一个更短的或没有暂停,如果脚本不打算永远死(当然,如果脚本真的从来没有死然后暂停实际上没有关系)。
请注意,@R_301_463@案不应涉及向现有脚本中添加文件锁定代码或PID记录。
更具体地说,我想要一个程序“daemonize”,我可以运行
% daemonize myscript arg1 arg2
或者,例如,
% daemonize 'echo `date` >> /tmp/times.txt'
这将保持日期的时间列表附加到times.txt。 (注意,如果daemonize的参数是一个永远运行的脚本,如上面case 1,然后daemonize仍然会做正确的事情,必要时重新启动它。)然后我可以在我的.login上面的命令和/或cron它每小时或分钟(取决于如何担心我是关于意外死亡)。
注意:守护进程脚本需要记住它是守护进程的命令字符串,所以如果同一个命令字符串再次进行守护进程,它不会启动第二个副本。
此外,该@R_301_463@案应该理想地在OS X和linux上工作,但欢迎一个或另一个的@R_301_463@案。
编辑:这是很好,如果你必须调用它与sudo daemonize myscript myargs。
(如果我想这个错误或有快速和脏的部分@R_301_463@案,我很想听到这一点。)
PS:如果它是有用的,here’s一个类似的问题特定于python。
解决方法
nohup yourScript.sh script args&
nohup命令允许您关闭shell会话,而不会杀死您的脚本,而&把你的脚本放在后台,这样你得到一个shell提示继续你的会话。唯一的小问题是标准输出和标准错误都发送到./nohup.out,所以如果你在这个庄园中启动几个脚本,它们的输出将是交织在一起的。更好的命令是:
nohup yourScript.sh script args >script.out 2>script.error&
这将标准输出到您选择的文件和标准错误到您选择的其他文件。如果你想只使用一个文件标准输出和标准错误,你可以我们这样:
nohup yourScript.sh script args >script.out 2>&1 &
2& 1告诉外壳将标准错误(文件描述符2)重定向到与标准输出(文件描述符1)相同的文件。
要运行一个命令只有一次,如果它死了重新启动它可以使用这个脚本:
#!/bin/bash if [[ $# < 1 ]]; then echo "Name of pid file not given." exit fi # Get the pid file's name. PIDFILE=$1 shift if [[ $# < 1 ]]; then echo "No command given." exit fi echo "Checking pid in file $PIDFILE." #Check to see if process running. PID=$(cat $PIDFILE 2>/dev/null) if [[ $? = 0 ]]; then ps -p $PID >/dev/null 2>&1 if [[ $? = 0 ]]; then echo "Command $1 already running." exit fi fi # Write our pid to file. echo $$ >$PIDFILE # Get command. COMMAND=$1 shift # Run command until we're killed. while true; do $COMMAND "$@" sleep 10 # if command dies immediately,don't go into un-ctrl-c-able loop done
第一个参数是要使用的pid文件的名称。第二个参数是命令。所有其他参数是命令的参数。
如果你把这个脚本命名为restart.sh,这就是你如何调用它:
nohup restart.sh pidFileName yourScript.sh script args >script.out 2>&1 &