如何在 FreeBSD(和 macOS)中守护 shell 脚本

Nor*_*ray 5 macos shell daemon freebsd darwin

我通常启动长时间运行的 shell 脚本的方式是

\n\n
% (nohup ./script.sh </dev/null >script.log 2>&1 & )\n
Run Code Online (Sandbox Code Playgroud)\n\n

重定向关闭stdin,然后重新stdout打开stderrnohup当所属进程退出时,停止 HUP 到达该进程(我意识到这有点2>&1多余,因为nohup无论如何它都会做类似的事情);子 shell 中的后台是双叉,这意味着./script.sh进程的父进程在仍在运行时已退出,因此它获取 init 进程作为其父进程。

\n\n

然而,这并不完全有效,因为当我退出调用它的 shell 时(当然,通常我是在远程计算机上执行此操作),它不会完全退出。我可以^C退出,这是可以的 \xe2\x80\x93 该进程确实按预期在后台进行。然而,我无法弄清楚需要/不发生什么^C,这让我很恼火。

\n\n

上面的操作似乎勾选了unix FAQ(问题 1.7)中的大部分框,除了我没有做任何事情来将该进程与控制终端分离,或者使其成为会话领导者。FreeBSD 上存在setsid(2) 调用,但不存在该setsid命令;据我所知,也没有明显的替代命令。当然,在 macOS 上也是如此。

\n\n

所以,问题是:

\n\n
    \n
  • setsid这个平台上是否有我失踪的不同名称的呼叫者?
  • \n
  • 当我退出调用 shell 时,到底发生了什么,我正在用 杀死^C?有什么办法可以咬我吗?
  • \n
\n\n

相关问题(例如12)要么回答略有不同的问题,要么假设存在该setsid命令。

\n\n

(这个问题多年来一直困扰着我,但因为我在这里所做的实际上并不起作用,所以我以前从未抽出时间去调查、被难住并询问它)。

\n

nba*_*ari 2

在 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.
Run Code Online (Sandbox Code Playgroud)

您也可以尝试使用主管,例如immortal 可用于两个平台:

pkg install immortal  # FreeBSD
brew install immortal # macOS
Run Code Online (Sandbox Code Playgroud)

要守护您的脚本和日志 ( stdout/stderr),您可以使用:

immortal /path/to/your/script.sh -l /tmp/script.log
Run Code Online (Sandbox Code Playgroud)

或者对于更多选项,您可以创建一个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
Run Code Online (Sandbox Code Playgroud)

然后运行它immortal -c my-service.yml

更多示例可以在这里找到: https: //immortal.run/post/examples

如果只想使用&nohup并将其保存到文件中,您可以将其添加到脚本中:stdoutstderr

#!/bin/sh
exec 2>&1

...
Run Code Online (Sandbox Code Playgroud)

exec 2>&1在这个答案中查看更多信息/sf/answers/916188101/

然后简单地打电话并检查该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.
Run Code Online (Sandbox Code Playgroud)