perl – 如何在UNIX中对任意脚本进行守护进程?

我想要一个守护进程,可以将任意,通用的脚本或命令变成 daemon

有两种常见的情况我想处理:

>我有一个应该永远运行的脚本。如果它死了(或重新启动),重新启动它。不要让有一个副本同时运行(检测副本是否已经运行,在这种情况下不启动它)。
>我有一个简单的脚本或命令行命令,我想永远重复执行(运行之间有一个短暂的停顿)。同样,不允许脚本的两个副本一次运行。

当然,在情况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。

this回答一个类似的问题有什么似乎是一个有用的成语,一个快速和脏的任意脚本的妖魔:

解决方法

你可以通过使用nohup和&运算符:
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 &

相关文章

忍不住在 PerlChina 邮件列表中盘点了一下 Perl 里的 Web 应用框架(巧的是 PerlBuzz 最近也有一篇相关...
bless有两个参数:对象的引用、类的名称。 类的名称是一个字符串,代表了类的类型信息,这是理解bless的...
gb2312转Utf的方法: use Encode; my $str = "中文"; $str_cnsoftware = encode("utf-8...
  perl 计算硬盘利用率, 以%来查看硬盘资源是否存在IO消耗cpu资源情况; 部份代码参考了iostat源码;...
1 简单变量 Perl 的 Hello World 是怎么写的呢?请看下面的程序: #!/usr/bin/perl print "Hello W...
本文介绍Perl的Perl的简单语法,包括基本输入输出、分支循环控制结构、函数、常用系统调用和文件操作,...