我在 Linux 上开发了一个 C 代码,我想执行一个二进制文件说,除了调用来执行二进制文件/usr/sbin/binary_program -p xxx
之外,还有其他方法吗?system()
3 回答
是的,而且通常system
不应该使用,至少出于以下原因:
- 它遭受 shell 引用问题的所有危险,所以除了硬编码的命令行之外的任何东西都有潜在的危险。
- 它不是线程安全的。
- 它会干扰调用程序中的信号处理。
- 除了退出状态之外,它无法从已执行的程序中获取输出,除非该命令将输出显式保存到文件中。
要执行外部程序,您应该使用posix_spawn
, 或fork
后跟exec
-family 函数之一。但是,如果可能的话,您应该避免依赖外部程序/命令,尤其是当直接在您的程序中完成工作会更容易且不易出错时。例如,我见过一些荒谬的用法,比如system("sleep 1");
代替sleep(1);
.
是的,您可以使用exec*
函数族。
http://pubs.opengroup.org/onlinepubs/9699919799/functions/execv.html
如果需要模拟你的行为system
可以fork
然后调用一个exec
函数。
POSIX页面system
说:
system() 函数的行为就像使用 fork() 创建子进程一样,并且子进程使用 execl() 调用 sh 实用程序,如下所示:
execl(<shell 路径>, "sh", "-c", command, (char *)0);
重要的是要意识到您可以同时运行多个程序,并通过管道(或其他进程间通信)进行通信。这主要是通过混合系统调用来实现的。
我强烈建议阅读Advanced Linux Programming或其他一些很好的书籍,解释更多(比我们在几分钟内可以做的)有关各种syscall(2)所涉及的内容,特别是fork(2)、pipe(2)、dup2(2) , execve(2) , waitpid(2)和其他几个(可能是poll(2)用于多路复用,例如避免圆形管道中的死锁)。该system(3)
函数构建在这些系统调用之上(和/bin/sh
)
那本高级 Linux 编程书有一整章专门讨论进程。
我还建议了解 Unix 命令 shell 的工作原理。要么通过研究一些简单的免费 shell(如sash
)的源代码,要么至少通过strace
-ing 它。
实际上,popen(3)比system(3)更有用。您可以获得伴随命令的输出。
一些库(Poco、Qt、Glib/GTK)也有强大的进程管理功能。
fork
创建了一个难以理解的新流程。一个新程序在同一个进程中启动execve
。
所有进程都是由fork
(或可能vfork
)创建的,除了少数由内核神奇地启动(/sbin/init
, /sbin/modprobe
, ...)