Bash

如何完全分離程序

  • April 20, 2019

我想生成一個程序並在頂層執行它,以便當 shell 退出時,該程序繼續執行。

我錯誤地認為 nohup 會這樣做,但是當我從 shell 退出(shell 是一個 lxc 容器,我 ssh 進入其中)並重新進入時,這個過程就消失了。

即使使用 nohup 或 disown 似乎(查看 pstree)該程序仍在呼叫 shell 下。

我嘗試了一些選項,setsid 似乎工作 - 但我在這裡的 nohup 做錯了嗎?

$ cat myproc
sleep 1234

$ myproc &
$ pstree -a | grep -B 3 "1234" | grep -v grep
 |-screen 
 |   |-bash -ls
 |   |   |-bash -ls
 |   |   |   `-sleep 1234


$ nohup myproc &
$ pstree 
 |-screen 
 |   |-bash -ls
 |   |   |-pstree -a
 |   |   `-sh ./myproc
 |   |       `-sleep 1234

$ myproc &
$ disown $!
$ pstree -a | grep -B 3 "1234" | grep -v grep
 |-screen 
 |   |-bash -ls
 |   |   |-bash -ls
 |   |   |   `-sleep 1234

$ setsid myproc &
 |-sh ./myproc
 |   `-sleep 1234

成功。但是為什麼 nohup 沒有達到同樣的效果呢?有沒有辦法更正確地使用 nohup?

這有點難以診斷,因為您沒有提供來源myproc,但我懷疑您的問題與“控制 TTY ”有關。我寫了一個小的 shell 腳本,它只呼叫sleep 100. 我在下面執行它nohup

$ nohup ./sleeper > sleeper.out &

[1] 25305
-bash-3.2$ jobs
[1]+  Running                 nohup ./sleeper > sleeper.out &
-bash-3.2$ ps -l -p 25305
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S 429624 25305 18252  0 77   0 - 15961 wait   pts/0    00:00:00 sleeper

如果您查看ps輸出,您會看到一個名為“ TTY ”的列。至少有一些版本nohup(我上面使用的版本來自 GNU coreutils,版本 5.97,所以相對較舊)。當我退出我開始的 bash shell 時sleeper,TTY 列更改為“?”,這意味著sleeper沒有。

如果myproc不故意將自己從它控制的 TTY 中分離出來,那麼如果它嘗試寫入標準輸出,它仍然有可能獲得像 SIGPIPE 信號這樣的東西。在我看來,其他事情是可能的,但我不記得或Google任何東西。

如果您可以找到或編譯“ daemonize ”,您可能想嘗試一下。如果myproc已編譯,您可以修改原始碼以呼叫daemon(3)庫函式。

引用自:https://unix.stackexchange.com/questions/156101