【发布时间】:2020-04-30 18:43:33
【问题描述】:
我通常启动长时间运行的 shell 脚本的方式是
% (nohup ./script.sh </dev/null >script.log 2>&1 & )
重定向关闭stdin,并重新打开stdout 和stderr; nohup 在拥有进程退出时停止 HUP 到达进程(我意识到 2>&1 有点多余,因为 nohup 无论如何都会这样做);子shell中的后台是双叉,这意味着./script.sh进程的父进程在它仍在运行时已经退出,因此它获取init进程作为其父进程。
这并没有完全工作,但是,因为当我退出我调用它的外壳时(通常,当然,我在远程机器上执行此操作),它没有干净地退出。我可以通过^C 退出,这没关系——该过程确实按预期在后台进行。但是我无法弄清楚需要^C 会发生什么/没有发生什么,这让我很恼火。
上述操作似乎勾选了unix FAQ(问题 1.7)中的大多数框,除了我没有做任何事情来将此进程与控制终端分离,或者使它是会话负责人。在 FreeBSD 上存在 setsid(2) 调用,但不存在 setsid 命令;据我所知,该命令也没有明显的替代品。当然,在 macOS 上也是如此。
所以,问题是:
- 在这个平台上是否有一个不同名称的调用者
setsid,我错过了? - 确切地说,当我退出调用 shell 时,我正在使用
^C杀死什么?有什么办法可以咬我吗?
相关问题(例如1、2)要么回答稍有不同的问题,要么假设存在setsid 命令。
(这个问题多年来一直困扰着我,但因为我在这里所做的实际上并没有奏效,所以我以前从未有过调查、难倒和询问的时间。
【问题讨论】:
-
你用的是什么外壳?
csh不喜欢你的语法,sh似乎完全没有问题地退出了。 -
它是 bash 和 zsh(当然不是 *csh),我认为使用 WM 并不复杂,因为我注意到这是我(完成)某处 ssh .不过,这肯定是一些微妙的事情......
-
对于
zsh,您可能需要使用&!而不是&才能完全拒绝父shell 的作业。 -
是的,
&!确实是“背景和否认”,但否认只是从工作表中删除,因此不受工作控制操作的影响(在我写这篇文章时,我意识到我'对'工作表'代表什么以及从它中删除意味着什么有一个稍微模糊的概念)。此外,上述后台进程确实从作业表中消失。 -
这里有一个很小的(一个 C 文件)
setsid程序,我一直在 MacOSX(BSD-ish,也缺少setsid)上使用:github.com/jerrykuch/ersatz-setsid
标签: macos shell daemon freebsd darwin