您的问题似乎需要一个森林答案,而这里的答案似乎就像是树的答案,所以我想给您一个森林答案。
这很少是C程序的编写方式。总是编写外壳脚本的方式,有时甚至是编写Python,perl或Ruby程序的方式。
人们通常使用C语言编写代码,以方便使用系统库,并直接对OS系统调用进行低级访问,以及提高速度。而且C是很难编写的语言,因此,如果人们不需要这些东西,那么他们就不会使用C。通常,C程序通常只依赖于共享库和配置文件。
壳化到子进程并不是特别快,并且不需要对低级系统设施进行细粒度和受控的访问,并且它引入了对外部可执行文件的可能令人惊讶的依赖关系,因此很少见到在C程序中。
还有一些其他问题。人们提到的安全性和可移植性问题是完全有效的。当然,它们对于Shell脚本同样有效,但是人们期望Shell脚本中出现此类问题。但是通常不期望C程序具有此类安全问题,这使其更加危险。
但是,我认为,popen
与程序其余部分交互的方式最重要的问题。popen
必须创建一个子进程,读取其输出并收集其退出状态。同时,该进程的stderr将与您的程序连接到同一stderr,这可能会导致混乱的输出,并且其stdin与您的程序相同,这可能会导致其他有趣的问题。您可以通过</dev/null 2>/dev/null
在传递的字符串中包含popen
它来解决此问题,因为它是由Shell解释的。
并popen
创建一个子进程。如果您自己对信号处理或派生处理进行任何操作,最终可能会收到奇怪的SIGCHLD
信号。您对的呼叫wait
可能会与popen
奇怪的比赛条件产生奇怪的互动,并可能会产生奇怪的比赛条件。
安全和可移植性问题在那里。因为它们是用于shell脚本或启动系统上其他可执行文件的任何东西。而且您必须小心,使用您的程序的人无法将shell元字符包含在您输入的字符串中,popen
因为该字符串是直接由sh
with 给出的sh -c <string from popen as a single argument>
。
但是我不认为这就是为什么使用C语言程序很奇怪popen
。之所以奇怪,是因为C通常是一种低级语言,而popen
不是低级语言。并且由于popen
在程序上使用了位置设计约束,因为它会与程序的标准输入和输出奇怪地交互,从而使您难以进行自己的过程管理或信号处理。而且,由于通常不希望C程序依赖于外部可执行文件。