我正在阅读并尝试在
Linux上使用C代码运行程序的不同可能性.我的用例涵盖了所有可能的场景,从简单的运行和忘记过程,阅读或写入过程,到阅读和写入过程.
对于前三个,popen()非常易于使用且运行良好.我知道它在内部使用了一些版本的fork()和exec(),然后调用一个shell来实际运行命令.
对于第三种情况,popen()不是一个选项,因为它是单向的.可用选项包括:
>手动fork()和exec(),以及输入/输出的pipe()和dup2()
> posix_spawn(),内部根据需要使用上述内容
我注意到的是,这些可以实现与popen()相同的功能,但我们可以完全避免调用额外的sh.这听起来很可取,因为它似乎不那么复杂.
但是,我注意到,即使我在互联网上发现的examples on posix_spawn()
确实调用了一个shell,所以它似乎必然会带来好处.如果它是关于解析命令行参数,wordexp()似乎也做了同样好的工作.
调用shell运行所需进程而不是直接运行它的好处是什么?
编辑:我意识到我的问题措辞没有准确地反映我的实际兴趣 – 我对通过sh而不是(历史)原因的好处更加好奇,虽然两者显然是相关的,所以两种变化的答案都是同样相关.
调用shell允许您执行在shell中可以执行的所有操作.
例如,
例如,
FILE *fp = popen("ls *","r");
可以使用popen()(展开当前目录中的所有文件).
比较它:
execvp("/bin/ls",(char *[]){"/bin/ls","*",NULL});
你不能用*作为参数执行ls,因为exec(2)将按字面解释*.
类似地,管道(|),重定向(>,<,...)等可能与popen一起使用. 否则,如果你不需要shell,就没有理由使用popen – 这是不必要的.你最终会得到一个额外的shell进程,所有在shell中出错的东西都可能在你的程序中出错(例如,你传递的命令可能会被shell错误地解释并出现常见的安全问题). popen()
is designed that way. fork exec解决方案更清晰,没有与shell相关的问题.