'su -c command'

时间:2016-01-07 03:22:15

标签: shell subprocess upstart

使用Upstart时,控制子进程(子进程)非常重要。但让我感到困惑的是如下,这已经超越了新贵本身:

方案1:

root@ubuntu-jstorm:~/Desktop# su cr -c 'sleep 20 > /tmp/a.out'

我有3个流程:cr@ubuntu-jstorm:~$ 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:

root@ubuntu-jstorm:~/Desktop# su cr -c 'sleep 20'

我有两个流程:cr@ubuntu-jstorm:~$ 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的过程是我关心的过程,特别是在Upstart中,由Upstart管理的过程应该是这个,而不是bash -c sleep 20 > /tmp/a.out由Upstart管理,而不是sleep 20

在方案1中,upstart无法正常工作,上面就是原因。

因此,为什么场景1有3个过程,这对我来说没有意义。即使我知道我可以使用命令'exec'来修复它,我只想获得程序在两个命令提交时发生的事情。

2 个答案:

答案 0 :(得分:0)

command > file

这不是原子动作,实际上是在2个过程中完成的。

一个是执行命令; 另一个是输出重定向。

以上两个动作无法在一个过程中完成。

我是对的吗?

答案 1 :(得分:0)

su -c启动shell并通过其-c选项传递命令。 shell可以生成任意数量的进程(取决于给定的命令)。

在某些情况下,shell似乎直接执行命令而不会分叉,例如,如果您运行su -c '/bin/sleep $$',那么表观行为就好像

  1. su启动了一个shell进程(例如/bin/sh
  2. shell获取自己的进程ID(PID)并用$$替换它
  3. 外壳exec() /bin/sleep
  4. 你应该在ps输出中看到sleep的参数在这种情况下等于它的pid。

    如果你运行su -c '/bin/sleep $$ >/tmp/sleep'那么/bin/sleep参数不同于它的PID(它等于祖先的PID),即:

    1. su启动了一个shell进程(例如/bin/sh
    2. shell获取自己的进程ID(PID)并用$$替换它
    3. shell 双叉exec() /bin/sleep
    4. 双叉表示实际的事件序列可能不同,例如,su可以协调分叉或不分叉,而不是shell(我不知道)。似乎是the double fork is there to make sure that the command won't get a controlling terminal