簡體   English   中英

在BASHRC和命令行中啟動后台進程之間的區別

[英]Difference between starting a background process in BASHRC vs Command Line

我正在嘗試自動后台處理進程。

nohup program > /tmp/program.log 2>&1 < /dev/null &
disown

如果我檢查進程是否正在運行,並通過“ .bashrc”在登錄時啟動它,則程序將啟動,但退出時會死掉。

但是,如果我在命令行上執行完全相同的命令,則退出時該程序將繼續在后台運行。

我找不到bashrc啟動和cli啟動之間的程序環境差異。 (bashrc中幾乎沒有任何內容)。 我對這兩種情況下的程序的理解應該相同。

有什么區別,以及如何在退出外殼時阻止bashrc啟動的“守護程序”被殺死。

PS:刪除nohup沒什么區別。 並且我已經看到程序運行,然后在退出初始登錄時從另一個登錄中消失。

在某人說什么之前...在bashrc中使該程序后台運行后添加“ disown”並不能解決問題!

更新:如果ssh登錄連接被終止(窗口關閉或連接突然終止),則在bashrc中啟動的程序將繼續運行,但這似乎是因為啟動它的bash仍在運行(至少暫時如此) 。 僅當您為bash鍵入“ exit”或殺死bash(即使信號為9!)時,背景才會被殺死。

程序的PPID(由Shell棄用)為0,即其父級不是Shell NOR初始化進程! 這種情況無論如何啟動。

更新2 ...后台程序從bashrc啟動...

# ps -jA w
   PID   PGID    SID TTY      STAT   TIME COMMAND
   891    891    891 pts/2    Ss+    0:00 /bin/bash
   899    891    891 pts/2    Sl+    0:00 program

我殺死了那個人,然后從命令行啟動了它。

   891    891    891 pts/2    Ss+    0:00 /bin/bash
   958    955    891 pts/2    Sl     0:00 program

現在,當外殼存在時,程序不會退出。 因此,看起來唯一的不同是PGID發生了變化。

如何在其他PGID中啟動流程?

作業控制需要進程組,因為外殼需要一些東西來將作業控制信號發送到,例如,當您鍵入fg POSIX.1-2017 狀態

支持作業控制的命令解釋器流程可以通過將相關流程置於單個流程組中並將該流程組與終端相關聯,從而將終端分配給不同的作業或流程組

(斜體字是我的)這似乎甚至等同於“進程組”和“作業”的概念,盡管大多數人將“作業”一詞用於注冊在操作系統中的進程組(甚至是外殼程序組中的子級)。外殼作業表 (並且可以通過內置的disown從該表中刪除)

因此,如果外殼程序不想在作業控制下啟動子命令(甚至外殼程序管道),則不會創建新的進程組(通過調用setpgrp()

發生這種情況,例如在使用流程替代時

blah=$(sleep 1000 | sleep 1000)

(嘗試一下,看看ps -jA w的輸出!),顯然是從.bashrc啟動命令時

nohup <command>本身不會啟動新的進程組,它只會忽略 SIGHUP ,然后執行command

Linux(以及安裝了util-linux類的其他OS)具有命令setid ,該命令可以完成 nohup 預期的操作 (但沒有得到): setsid command將為<command> 創建一個新的進程組並使其生效新會議的會議負責人。 該新進程組的PGID對於調用者而言將是未知的(在本例中為bash ),因此我們不再需要使用nohup

因此,使用setsid代替nohup ,您就完成了(我現在只看到Mark Plotnick的評論,這對您來說是對的。哦,好吧,我希望我的回答也能闡明在這種情況下setsid是更好的選擇的原因

好吧...看來問題實際上是由環境引起的。

該外殼程序正在docker容器中運行。 似乎Docker Exec是終止同一進程組中所有進程的終端,而不是Shell。 或者至少看起來是這樣。

但是,我仍然感到奇怪的是,以“ .bashrc”為背景的程序繼承了與父外殼程序相同的進程組,但是從命令行獲得的完全相同的后台命令卻獲得了自己的單獨進程組。

一旦找到了原因,就發現在BASH聯機幫助頁中提到了有關進程后台的過程組,盡管它沒有提及“ .bashrc”與CLI的區別。

每個bash進程都有一個PPID(父PID)

如果從終端運行以下命令:

nohup tail -f /dev/null > /tmp/rand.txt &

ps -ef輸出中的PPID顯示PPID是init(首先啟動的進程):

UID        PID  PPID  C STIME TTY          TIME CMD
user     18424     1  0 16:17 tty1     00:00:00 tail -f /dev/null

如果從bashrc運行相同的命令,則PPID是bash進程:

UID        PID  PPID  C STIME TTY          TIME CMD
user     16405 16404  0 Jun20 tty2     00:00:08 bash
user     18424 18386  0 16:17 tty1     00:00:00 tail -f /dev/null

從終端運行時,該過程將繼續進行,直到停止初始化為止。

從bashrc運行時,該過程將繼續直到bash停止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM