为什么popen()会调用shell来执行进程?

前端之家收集整理的这篇文章主要介绍了为什么popen()会调用shell来执行进程?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在阅读并尝试在 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相关的问题.

原文链接:https://www.f2er.com/bash/385025.html

猜你在找的Bash相关文章