2016-01-07 181 views
0

使用Upstart時,控制子進程(子進程)非常重要。但是,什麼困惑我的是如下,這已經超越了新貴本身:'su -c command'生成的子進程的數量(子進程)

場景1:[email protected]:~$ ps -ef | grep -v grep | grep sleep

root  8026 6544 0 11:11 pts/2 00:00:00 su cr -c sleep 20 > /tmp/a.out 
cr   8027 8026 0 11:11 ?  00:00:00 bash -c sleep 20 > /tmp/a.out 
cr   8028 8027 0 11:11 ?  00:00:00 sleep 20 

場景2:

[email protected]:~/Desktop# su cr -c 'sleep 20 > /tmp/a.out' 

我用了3個進程

[email protected]:~/Desktop# su cr -c 'sleep 20' 

我有兩個過程是:[email protected]:~$ ps -ef | grep -v grep | grep sleep

root  7975 6544 0 10:03 pts/2 00:00:00 su cr -c sleep 20 
cr   7976 7975 0 10:03 ?  00:00:00 sleep 20 

sleep 20的過程是一個我關心,尤其是暴發戶,由新貴管理的過程應該是這樣的,而不是bash -c sleep 20 > /tmp/a.out由暴發戶管理,而而不是sleep 20

在場景1中,暴發戶無法正常工作,以上是原因。

因此,爲什麼場景1有3個過程,這對我來說沒有意義。即使我知道我可以使用命令'exec'來修復它,但我只想獲得當兩個命令提交時發生的情況。

+0

它看起來像[XY問題](http://meta.stackexchange.com/a/66378/137096)。你真正的問題是什麼?忘了'su',你想用'upstart'運行什麼命令?描述你期望發生什麼以及發生什麼。 – jfs

回答

0

su -c啓動shell並通過它的-c選項將命令傳遞給它。 shell可能會產生儘可能多的進程(取決於給定的命令)。

看來殼執行該命令的情況下直接在某些情況下例如分叉,如果運行su -c '/bin/sleep $$'然後表觀行爲彷彿

  1. su啓動一個外殼進程(例如,/bin/sh
  2. shell獲取自己的進程ID(PID)並用它替代$$
  3. shell exec()/bin/sleep

您應該在ps輸出中看到sleep的參數與本例中的pid相等。

如果運行su -c '/bin/sleep $$ >/tmp/sleep'然後/bin/sleep說法是從它的PID不同(這等於祖先的PID),即:

  1. su啓動一個外殼程序(例如,/bin/sh
  2. 外殼獲取其自己的進程ID(PID)並用它替代$$
  3. 雙叉exec()/bin/sleep

雙叉指示事件的實際順序可能不同,例如,su可以編排分叉或不分叉,而不是shell(我不知道)。看起來好像是the double fork is there to make sure that the command won't get a controlling terminal

+0

使用$$作爲參數睡眠真的很聰明!謝謝!並且,給我帶來「雙重叉子」,這是........專家級別,並樂於學習它。 – Cross

+0

@Cross:關於雙叉和更多關於'setsid()'和確保該進程不是會話領導者(因此它不能控制終端)](http://stackoverflow.com/問題/ 881388 /什麼,是最有理由換執行-A-雙叉時創造的,一個守護進程/ 881415#comment23366466_881408)。請注意,即使[已建立的命令(例如'sudo')可能會改變其與會話/進程組/控制終端相關的行爲](http://stackoverflow.com/q/34337840/4279) – jfs

0
command > file 

這不是原子操作,實際上是在2個過程中完成的。

一個是執行命令; 另一個做輸出重定向。

以上兩個操作無法在一個進程中完成。

對嗎?

+0

不要發佈問題作爲答案。如果它與當前問題相關,請[編輯您的問題](http://stackoverflow.com/posts/34646851/edit)。否則,請提出一個新問題。 – jfs