csh 上没有 nohup,ssh 退出后后台作业仍在运行

csh 上没有 nohup,ssh 退出后后台作业仍在运行

nohup我试图了解在 ssh 中使用后台命令的需要。我的 shell 在 CentOS 上是 csh。

  1. 即使 ssh 退出后,下面的后台命令也会继续运行。我预计只有在nohup命令前面加上前缀才会发生这种情况。

    什么场景下nohup会需要?

     ssh host 'sleep 80 >& /dev/null &'
    
  2. 我也尝试了交互式shell,ssh退出后后台作业的PID仍然存在于主机上。

     ssh host sleep 80 >& /dev/null & exit
    
  3. kill -HUP PID我还尝试使用而不是终止交互式会话exit,并且在ssh退出后后台作业的PID仍然存在于主机上。

我做错了什么吗?

答案1

不,一个背景默认情况下,当会话领导者(shell)退出或其控制终端被拆除时,进程组(作业)不会被终止。

只有一些特殊情况才会发生这种情况:

(1)后台作业是停止了SIGHUP,在这种情况下,它将由/发送一SIGCONT对信号核心。如果SIGHUP进程没有捕获或忽略该信号,则该进程将终止。

已停止作业的定义是:任何包含已停止进程的作业。一个过程睡眠nanosleep(2)在诸如或 之类的阻塞系统调用上,read(2)不被视为已停止。

(2)进程尝试读取或写入不再存在的终端,并由于尝试执行此操作时出现错误而(自行)退出。

(3)这份工作实际上是一个前景工作。这核心SIGHUP当会话领导者/控制进程(即 shell)终止时,向前台进程组发送信号。SIGHUP当控制终端被拆除时,控制进程本身会收到信号,这通常会导致其终止。

即使以开头的命令&实际上也是前景当它们从没有作业控制的 shell 启动时(在大多数 shell 中——但不是在 csh 中——是运行时的默认设置)脚本子壳)。

(4)bash您正在使用像or 这样的 shell zshSIGHUP当它本身收到信号时SIGHUP(根据上面的第 3 点,shell 是控制进程),或者只是当它退出时(后者只是 中的默认值zsh,但不是默认值并受shopt huponexitbash 中的选项约束)。

外壳程序(真实的cshtcsh没有这种行为bashzsh。在tcsh(但不是在真实的csh)中,您可以使用内置命令启动命令hup,以便在 shell 退出时对其进行 hup 操作:

tcsh% hup sleep 3600 &
tcsh% exit
$ pgrep sleep
[nothing]

(5)您的 init 系统会不遗余力地清理任何终止的用户会话。在其默认配置下,系统会向所有进程发出信号范围延迟后跟随一个,所以无论如何SIGTERM都不会帮助你。另外,systemd 的想法是SIGKILLnohup范围与 Unix 进程会话不匹配,因此运行命令setsid(1)也不会让它逃脱。

您可以通过调整 、 和 选项的默认值来更改KillUserProcesses=yessystemdKillMode=control-groupKillSignal=SIGTERM行为SendSIGKILL=yes

相关内容