【问题标题】:How to daemonise a shell-script in FreeBSD (and macOS)如何在 FreeBSD(和 macOS)中守护 shell 脚本
【发布时间】:2020-04-30 18:43:33
【问题描述】:

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

% (nohup ./script.sh </dev/null >script.log 2>&1 & )

重定向关闭stdin,并重新打开stdoutstderrnohup 在拥有进程退出时停止 HUP 到达进程(我意识到 2&gt;&amp;1 有点多余,因为 nohup 无论如何都会这样做);子shell中的后台是双叉,这意味着./script.sh进程的父进程在它仍在运行时已经退出,因此它获取init进程作为其父进程。

这并没有完全工作,但是,因为当我退出我调用它的外壳时(通常,当然,我在远程机器上执行此操作),它没有干净地退出。我可以通过^C 退出,这没关系——该过程确实按预期在后台进行。但是我无法弄清楚需要^C 会发生什么/没有发生什么,这让我很恼火。

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

所以,问题是:

  • 在这个平台上是否有一个不同名称的调用者setsid,我错过了?
  • 确切地说,当我退出调用 shell 时,我正在使用 ^C 杀死什么?有什么办法可以咬我吗?

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

(这个问题多年来一直困扰着我,但因为我在这里所做的实际上并没有奏效,所以我以前从未有过调查、难倒和询问的时间。

【问题讨论】:

  • 你用的是什么外壳? csh 不喜欢你的语法,sh 似乎完全没有问题地退出了。
  • 它是 bash 和 zsh(当然不是 *csh),我认为使用 WM 并不复杂,因为我注意到这是我(完成)某处 ssh .不过,这肯定是一些微妙的事情......
  • 对于zsh,您可能需要使用&amp;! 而不是&amp; 才能完全拒绝父shell 的作业。
  • 是的,&amp;! 确实是“背景和否认”,但否认只是从工作表中删除,因此不受工作控制操作的影响(在我写这篇文章时,我意识到我'对'工作表'代表什么以及从它中删除意味着什么有一个稍微模糊的概念)。此外,上述后台进程确实从作业表中消失。
  • 这里有一个很小的(一个 C 文件)setsid 程序,我一直在 MacOSX(BSD-ish,也缺少 setsid)上使用:github.com/jerrykuch/ersatz-setsid

标签: macos shell daemon freebsd darwin


【解决方案1】:

在 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.

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

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.run/post/examples

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

#!/bin/sh
exec 2>&1

...

在这个答案https://stackoverflow.com/a/13088401/1135424中查看更多关于exec 2&gt;&amp;1的信息

然后只需调用nohup /your/script.sh &amp; 并检查来自man 的文件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.

【讨论】:

  • 谢谢你,@nbari:daemon 命令看起来很有趣,我可以看到一些有用的情况,查看the source 我发现它可以通过调用 daemon(3 )。然而,我提出问题的主要动机是为什么高层的行动——它们完成了大部分工作——并不是完整的故事。这是一个“我在误解什么?”发自内心的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-13
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
  • 2013-09-22
  • 2015-05-23
  • 2011-03-26
相关资源
最近更新 更多