C popen创建了一个额外的sh进程

C popen创建了一个额外的sh进程,c,exec,process,popen,ps,C,Exec,Process,Popen,Ps,我试图用popen执行(fork off)一个命令,我看到的是,还有一个额外的sh-c“my_command process” 我想尽量减少进程的数量,所以有可能摆脱它吗 ps输出: root@home% ps awux | grep my_command root 638 0.0 0.1 040 1424 ?? I 10:12PM 0:00.00 sh -c my_command /home/war root 639 0.0 0.0 608 932 ?? S

我试图用popen执行(fork off)一个命令,我看到的是,还有一个额外的
sh-c“my_command process”

我想尽量减少进程的数量,所以有可能摆脱它吗

ps输出:

root@home% ps awux | grep my_command
root 638  0.0  0.1  040  1424  ??  I    10:12PM   0:00.00 sh -c my_command /home/war
root 639  0.0  0.0  608   932  ??  S    10:12PM   0:00.01 my_command /home/war
阅读了手册页后,我知道popen()就是这样工作的

以上问题的答案由@R.提供


我的要求是,我需要将命令的输出转储到一个文件中,逐行读取该文件并处理输出。这就是为什么我使用popen,因为它在文件中返回输出。我可以通过任何exec调用实现吗?

popen
使用
sh
生成子进程,就像POSIX系统上的
system
一样


如果您想避免它,只需使用
fork
close
mkpipe
exec
(这或多或少是
popen
内部的功能)。如果您不需要管道,只需
fork
exec

就popen而言,它应该调用shell(阅读手册页)


要跳过shell过程,您可以执行fork/exec

您应该听取好的人的意见,他们建议您不要使用
popen
——这很糟糕。但是对于您遇到的问题,有一个简单的解决方案-将
exec
添加到传递给
popen
的命令行的开头。也就是说,而不是:

popen("my_command /home/war", ...
使用:


向我们展示代码的相关部分。如果这就是popen()的工作原理,那么我的另一个选择是什么?@aix:为什么?我相信这个问题是自给自足的。是吗?@hari:如果——差不多7年后——你仍然对为什么使用额外的
sh
过程感兴趣(正如你在下面的评论中所指出的),我已经问了一个问题。谢谢你的回答。就我的教育而言,波本为什么这么做?如果可以避免的话。为什么要创建一个额外的进程?使用shell作为中间步骤可以让代码使用shell内置/工具。我看不出还有什么比这更好的。不过,正如前面所解释的,使用syscalls可以很容易地避免它。即使设置了execute位,您仍然需要通过sh或bash传递它(在shell脚本上运行exec失败)。因此,由于不需要将任何程序实现为c程序,因此您可能希望使用shell脚本,并且只需通过shell就更容易了。(其他脚本,如python和perl,在shell解析shebang行时由shell解析,因此也支持其他脚本)@Foo-Bah:IIRC实际上,shebang符号是由
exec
直接处理的,不需要shell。另外(同样,IIRC)当您从一个shell启动一个shell脚本时,该shell进程不会被重用,但会启动另一个进程(除非您使用
命令)。我迟到了,但我倾向于同意@MatteoItalia:至少该脚本明确声明:“execve()执行文件名指向的程序。文件名必须是二进制可执行文件,或者是以以下行开头的脚本:
#!解释器[可选参数]
“-这也适用于
execvp
,因为其手册页引用了
execve
-不确定该系列的其他功能。谢谢。我肯定会听取每个人的意见。我只是想弄明白为什么它不好。如果不好,为什么要这样设计/实施/标准化/使用。再次感谢我的教育:)非常感谢。这很糟糕,因为。。(1) 如果不小心引用,通过shell调用外部程序会引入shell meta char vulns,(2)
popen
只允许单向通信,而不允许双向通信,(3)您无法访问子进程的pid,因此如果您想
等待所创建的其他子进程,就会出现问题。可能还有其他问题……同意(1)和(3)。popen是如何进行单向沟通的?谢谢。@hari大多数实现只允许
popen(“…”,“r”)
popen(“…”,“w”)
。也就是说,你只能写或读。作为例外,BSD允许“r+”。
popen("exec my_command /home/war", ...