C语言中popen()和system()有什么区别?

30
我希望在我的C代码中执行一个二进制文件。使用哪种方法更好?popen()还是system()编辑:我尝试使用system,但执行的进程似乎在最后卡住了,并且没有返回到我的代码。
有什么建议吗?
谢谢

5
man popenman system 是 Linux 中的两个命令。 man popen 用于打开一个进程,并建立一个管道以进行读写操作。 man system 则用于在新的 shell 中执行一个命令。 - Some programmer dude
你尝试过使用popen()吗?或者是你的二进制文件有问题?你最后一次的编辑有点令人困惑。 - henryyao
使用 popen 而不是 system 并不能解决您实际遇到的问题:进程卡住了。 - Wolf
2个回答

45

popen() 函数可以控制进程的输入或输出文件流,system() 函数则不能。如果您不需要访问进程的 I/O,则可以使用 system() 函数以简化操作。

system() 函数可用于 C89 和 C99,而 popen() 函数只能在 Posix 系统上使用(尽管 Windows API 也有一个类似函数)。

这两个函数都会调用某种形式的 shell 来执行命令(例如,在 Linux 上使用 /bin/sh,在 Windows 上可能使用 cmd.exe)。如果您想要直接执行可执行文件并且您正在使用 Posix 系统,则还可以查看 exec* 函数族与 fork() 结合使用(由于 exec() 函数会替换当前进程)。


1
@HeathHunnicutt:直到五分钟前,我才按照Joachim的建议去做。 - Kerrek SB
5
关于 popen 的重要提示:它只能控制输入 或者 输出流,而不能同时控制两者。 - Some programmer dude
5
当然。也许我应该写“xor”?不幸的是,英语和C编程语言是不同的。 - Kerrek SB
最近的测试显示,我从pclose返回的退出代码与命令的值乘以256相乘,例如对于退出代码43,我得到的值是11008。为什么会这样?但至少我得到了我的退出代码。 - Strubbl
1
@Strubbl:它的语义与“wait”相同,即您必须使用这些宏来确定进程是正常返回还是通过信号返回,然后移动返回值。 - Kerrek SB
显示剩余2条评论

5
如果您想运行一个 shell 命令并希望父进程能够与子进程通信,请使用 popen。它将子进程的输入或输出连接到返回的流上。否则,最好使用 exec 函数族(很可能与 fork 一起使用);exec 的进程会继承大多数打开的文件描述符(包括 stdin、stdout 和 stderr),因此您可以将输入和输出连接到您喜欢的任何位置...而且,安全风险更少。
通常应避免使用 system,除非必须运行 shell 命令。它生成一个 shell 来运行命令,并且 shell 可以以任何希望的方式解析命令。特别地,某些环境变量(如 $IFS 和/或 $PATH)可能被修改,从而导致父进程执行您从未打算执行的程序。虽然 popen 看起来也是这样做的,但至少它提供了使其在一般情况下值得使用的功能。

你只能做输入或输出中的一个,我想。popen()也会生成一个shell。 - Kerrek SB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接