2016-01-07 149 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