我通常启动一个长期运行的shell脚本的方法是
% (nohup ./script.sh </dev/null >script.log 2>&1 & )
重定向接近 stdin
,并重开 stdout
和 stderr
;该 nohup
当拥有的进程退出时,停止HUP到达进程(我意识到这个 2>&1
是有点多余的,因 nohup
反正是这样的);而子壳内的背景是双叉,这意味着 ./script.sh
进程的父进程已经退出,而它还在运行,所以它将 init 进程作为它的父进程。
这并不是 彻底 的工作,但是,因为当我退出我所调用的shell时(当然,通常情况下,我是在远程机器上这样做的),它并没有干净地退出。 我可以做 ^C
退出,这样做是正确的--该过程确实在后台按计划进行。 但是我不知道是什么事情没有发生,以至于需要在后台进行。^C
这让我很恼火。
上面的动作似乎勾选了大部分的框框。unix常见问题 (问题1.7)。除了 我没有做任何事情将这个进程从控制终端中分离出来, 也没有让它成为会话领导。 setsid(2) 调用在FreeBSD上是存在的, 但在FreeBSD上并不存在 setsid
命令;就我所见,也没有明显的替代命令。 当然,在macOS上也是如此。
所以,问题是。
setsid
在这个平台上,我错过了什么?^C
? 这有什么办法能咬住我吗?相关问题(例如 1, 2)或者回答的问题稍有不同,或者假设存在的。setsid
命令。
这个问题困扰了我很多年,但因为我这里做的事情其实并不是不能用,所以之前一直没来得及调查,被绊住了,就问了一下)。
在FreeBSD中,开箱即用的是 daemon -- run detached from the controlling terminal
.选项 -r
可能是有用的。
-r Supervise and restart the program after a one-second delay if it
has been terminated.
你也可以尝试一个主管,例如: 不朽 可用于这两个平台。
pkg install immortal # FreeBSD
brew install immortal # macOS
要守护你的脚本和日志 (stdout/stderr
),你可以使用。
immortal /path/to/your/script.sh -l /tmp/script.log
或者为了更多的选择,你可以创建一个 my-service.yml
比如说。
cmd: /path/to/script
cwd: /your/path
env:
DEBUG: 1
ENVIROMENT: production
log:
file: /tmp/app.log
stderr:
file: /tmp/app-error.log
然后运行它与 immortal -c my-service.yml
更多的例子可以在这里找到。https:/immortal.runpostexamples。
如果只是想使用 nohup
并保存 stdout
& stderr
到一个文件中,你可以将其添加到你的脚本中。
#!/bin/sh
exec 2>&1
...
查看更多关于 exec 2>&1
在这个答案中 https:/stackoverflow.coma130884011135424。
然后简单地调用 nohup /your/script.sh &
并检查文件 nohup.out
,来自 男人
FILES
nohup.out The output file of the nohup execution if stan-
dard output is a terminal and if the current
directory is writable.
$HOME/nohup.out The output file of the nohup execution if stan-
dard output is a terminal and if the current
directory is not writable.