加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-15 18:23:21 所属栏目:安全 来源:网络整理
导读:我正在阅读并尝试在 Linux上使用C代码运行程序的不同可能性.我的用例涵盖了所有可能的场景,从简单的运行和忘记过程,阅读或写入过程,到阅读和写入过程. 对于前三个,popen()非常易于使用且运行良好.我知道它在内部使用了一些版本的fork()和exec(),然后调用一个
我正在阅读并尝试在 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相关的问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读