dre*_*ves 91 unix sysadmin scripting perl daemon
我想要一个可以将任意通用脚本或命令转换为守护进程的守护进程.
我想要处理两种常见情况:
我有一个应该永远运行的脚本.如果它死了(或重启),重新启动它.不要让一次运行两个副本(检测副本是否已经在运行并且在这种情况下不启动它).
我有一个简单的脚本或命令行命令,我希望永远重复执行(运行之间的短暂停顿).同样,不要允许一次运行两个脚本副本.
当然,在案例2中围绕脚本编写"while(true)"循环然后为案例1应用解决方案是微不足道的,但更通用的解决方案将直接解决案例2,因为它适用于案例1中的脚本好(你可能只是想更短或没有停顿如果脚本不打算会死(当然,如果剧本真的没有永远不死,则暂停实际上并不重要)).
请注意,解决方案不应涉及将文件锁定代码或PID记录添加到现有脚本中.
更具体地说,我想要一个程序"daemonize",我可以运行
% daemonize myscript arg1 arg2
Run Code Online (Sandbox Code Playgroud)
或者,例如,
% daemonize 'echo `date` >> /tmp/times.txt'
Run Code Online (Sandbox Code Playgroud)
这将保留越来越多的日期列表附加到times.txt.(注意,如果daemonize的参数是一个永远运行的脚本,如上面的情况1那样,那么daemonize仍然会做正确的事情,必要时重新启动它.)然后我可以在我的.login中输入如上所示的命令和/或每小时或每小时一次(取决于我是多么担心它会意外死亡).
注意:daemonize脚本需要记住它正在守护的命令字符串,这样如果再次守护同一个命令字符串,它就不会启动第二个副本.
此外,理想情况下,该解决方案应该适用于OS X和Linux,但欢迎使用其中一种解决方案.
编辑:如果你必须调用它,这很好sudo daemonize myscript myargs
.
(如果我认为这一切都错了,或者有快速和肮脏的局部解决方案,我也很乐意听到.)
PS:如果它有用,这里是一个特定于python的类似问题.
而这个回答类似的问题有什么似乎是一个任意脚本的快速和肮脏的妖魔化一个有用的成语:
Rob*_*eer 89
您可以使用nohup和&运算符来守护Unix中的任何可执行文件:
nohup yourScript.sh script args&
Run Code Online (Sandbox Code Playgroud)
nohup命令允许您在不杀死脚本的情况下关闭shell会话,而将脚本放在后台,以便获得shell提示继续会话.唯一的小问题是标准输出和标准错误都被发送到./nohup.out,所以如果你在这个庄园中启动几个脚本,他们的输出将交织在一起.更好的命令是:
nohup yourScript.sh script args >script.out 2>script.error&
Run Code Online (Sandbox Code Playgroud)
这会将标准输出发送到您选择的文件和标准错误到您选择的其他文件.如果您只想将一个文件用于标准输出和标准错误,您可以这样做:
nohup yourScript.sh script args >script.out 2>&1 &
Run Code Online (Sandbox Code Playgroud)
2>&1告诉shell将标准错误(文件描述符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
Run Code Online (Sandbox Code Playgroud)
第一个参数是要使用的pid文件的名称.第二个参数是命令.所有其他参数都是命令的参数.
如果您将此脚本命名为restart.sh,则可以使用以下命令:
nohup restart.sh pidFileName yourScript.sh script args >script.out 2>&1 &
Run Code Online (Sandbox Code Playgroud)
Chr*_*ung 32
我为长篇答案道歉(请参阅关于我的答案如何指出规范的评论).我正在努力做到全面,所以你尽可能地保持优势.:-)
如果您能够安装程序(具有超级用户权限),并且愿意为执行守护程序执行而设置一次性脚本(即,更简单地指定要在命令行上运行的命令行参数,但是每个服务只需要做一次),我有一种更健壮的方式.
它涉及使用daemontools.本文的其余部分介绍了如何使用daemontools设置服务.
/service
.安装程序应该已经完成此操作,但只是验证或手动安装.如果您不喜欢这个位置,您可以在svscanboot
脚本中更改它,尽管大多数daemontools用户习惯使用/service
,如果您不使用它会感到困惑.init
(即不使用/etc/inittab
),则需要使用预安装inittab
作为安排svscanboot
调用的基础init
.这并不难,但您需要知道如何配置init
您的操作系统使用的.
svscanboot
是一个调用的脚本svscan
,它执行寻找服务的主要工作; 它是从所谓init
所以init
会安排如果死以任何理由重新启动它./var/lib/svscan
,但任何新的位置都可以.我通常使用脚本来设置服务目录,以节省大量的手动重复性工作.例如,
sudo mkservice -d /var/lib/svscan/some-service-name -l -u user -L loguser "command line here"
Run Code Online (Sandbox Code Playgroud)
这里some-service-name
是你想给你的服务的名称,user
是运行服务为用户,并且loguser
是运行记录仪的用户.(记录稍作解释.)
fghack
,虽然这是一个权衡:您无法再使用控制程序svc
.run
脚本以确保它正在执行您想要的操作.sleep
如果您希望自己的服务经常退出,则可能需要在顶部拨打电话./service
指向服务目录时创建符号链接.(不要直接将服务目录放在其中/service
;这使得从svscan
手表中删除服务变得更加困难.)mkservice
); svscan
负责将日志消息发送到日志记录服务.mkservice
将在log/main
目录中创建自动轮换的带时间戳的日志文件.调用当前日志文件current
.tai64nlocal
会将时间戳转换为人类可读的格式.(TAI64N是64位原子时间戳,具有纳秒计数.)svstat
得到一个服务的状态.请注意,日志记录服务是独立的,并且具有自己的状态.svc
.例如,要重新启动您的服务,请使用svc -t /service/some-service-name
; -t
意思是"发送SIGTERM
".-h
(SIGHUP
),-a
(SIGALRM
),-1
(SIGUSR1
),-2
(SIGUSR2
)和-k
(SIGKILL
).-d
.您还可以通过创建down
服务目录中指定的文件来阻止服务在启动时自动启动.-u
.这是没有必要的,除非您之前已经将它击倒(或将其设置为不自动启动).-x
; 通常用于-d
终止服务.这是允许删除服务的常用方法,但您必须首先取消服务链接/service
,否则svscan
将重新启动主管.此外,如果您使用日志服务(mkservice -l
)创建服务,请记住svc -dx /var/lib/svscan/some-service-name/log
在删除服务目录之前也退出日志记录主管(例如).优点:
init
.缺点:
svc
,并且不能直接运行运行脚本(因为它们不会受到主管的控制).supervise
在你的进程表的过程.)总而言之,我认为daemontools是一个满足您需求的出色系统.我欢迎任何有关如何设置和维护它的问题.
uth*_*ark 12
你应该看看daemonize.它允许检测第二个副本(但它使用文件锁定机制).它也适用于不同的UNIX和Linux发行版.
如果需要自动启动应用程序作为守护程序,则需要创建适当的init-script.
您可以使用以下模板:
#!/bin/sh
#
# mydaemon This shell script takes care of starting and stopping
# the <mydaemon>
#
# Source function library
. /etc/rc.d/init.d/functions
# Do preliminary checks here, if any
#### START of preliminary checks #########
##### END of preliminary checks #######
# Handle manual control parameters like start, stop, status, restart, etc.
case "$1" in
start)
# Start daemons.
echo -n $"Starting <mydaemon> daemon: "
echo
daemon <mydaemon>
echo
;;
stop)
# Stop daemons.
echo -n $"Shutting down <mydaemon>: "
killproc <mydaemon>
echo
# Do clean-up works here like removing pid files from /var/run, etc.
;;
status)
status <mydaemon>
;;
restart)
$0 stop
$0 start
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
exit 1
esac
exit 0
Run Code Online (Sandbox Code Playgroud)
Ale*_*x B 11
我想你可能想试试start-stop-daemon(8)
./etc/init.d
在任何Linux发行版中查看脚本以获取示例.它可以通过命令行调用或PID文件找到启动的进程,因此它匹配您的所有要求,除了作为脚本的监视程序.但是,您可以随时启动另一个守护程序监视程序脚本,只需在必要时重新启动您的脚本.
如果你专门使用OS X,我建议你看看launchd是如何工作的.它将自动检查以确保您的脚本正在运行,并在必要时重新启动它.它还包括各种调度功能等.它应满足要求1和2.
至于确保只能运行一个脚本副本,您需要使用PID文件.通常我会将文件写入/var/run/.pid,其中包含当前运行实例的PID.如果文件在程序运行时存在,它会检查文件中的PID是否实际正在运行(程序可能已崩溃或以其他方式忘记删除PID文件).如果是,则中止.如果没有,请开始运行并覆盖PID文件.
Daemontools(http://cr.yp.to/daemontools.html)是由dj bernstein编写的一组非常硬核的实用工具.我已经成功地使用了它.令人讨厌的部分是,当你运行它们时,没有任何脚本返回任何可见的结果 - 只是不可见的返回码.但是一旦它运行它的防弹.
归档时间: |
|
查看次数: |
36948 次 |
最近记录: |