我通常启动一个长时间运行的shell脚本的方法是
% (nohup ./script.sh </dev/null >script.log 2>&1 & )
重定向关闭stdin
,并重新打开stdout
和stderr
;当拥有进程退出时,nohup
阻止HUP到达进程(我意识到2>&1
有点多余,因为nohup
无论如何都会这样做);子shell中的背景是double-fork,这意味着./script.sh
进程的父进程在仍在运行时已退出,因此它获取init进程作为其父进程。
然而,这并不完全有效,因为当我退出调用this的shell时(当然,通常我是在远程机器上执行此操作),它不会干净地退出。我可以执行^C
来退出,这是可以的--该过程确实按预期在后台进行。然而,我不能弄清楚什么是/不是发生需要^C
,这是恼人的我。
上面的操作似乎勾选了unix FAQ(问题1.7)中的大多数框,* 除了 * 我没有做任何事情来将此进程从控制终端分离,或者使其成为会话领导者。setsid(2)调用存在于FreeBSD上,但不存在setsid
命令;据我所知,也没有明显的替代品。当然,在macOS上也是如此。
所以,问题是:
- 在这个平台上是否有一个我遗漏的
setsid
的不同名称的调用者? - 当我退出调用shell时,我用
^C
杀死了什么?这东西会咬我吗
相关问题(例如1、2)要么回答一个稍微不同的问题,要么假设存在setsid
命令。
(This这个问题困扰了我很多年,但因为我在这里做的事情实际上并不起作用,我以前从来没有抽出时间去调查,被难倒,并询问它)。
2条答案
按热度按时间doinxwow1#
在FreeBSD中,你可以使用
daemon -- run detached from the controlling terminal
。选项-r
可能有用:您也可以尝试使用supervisor,例如immortal可用于两个平台:
要将脚本和日志(
stdout/stderr
)守护进程化,您可以用途:或者,对于更多选项,您可以创建
my-service.yml
,例如:然后用
immortal -c my-service.yml
运行它更多的例子可以在这里找到:https://immortal.run/post/examples
如果只是想使用
nohup
并将stdout
和stderr
保存到一个文件中,您可以将其添加到脚本中:查看更多关于
exec 2>&1
在这个答案https://stackoverflow.com/a/13088401/1135424然后简单地调用
nohup /your/script.sh &
并检查文件nohup.out
,从manzfycwa2u2#
DJB提供了daemontools-encore,用于将任何程序作为守护进程运行,包括shell脚本。他有一整套运行TCP服务器的工具,包括速率限制和用户隔离。