属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
system()Thread safetyMT-Safe

返回值

system()的返回值为以下之一:

*
如果command为NULL,那么如果有可用的shell,则为非零值;如果没有可用的shell,则为0。
*
如果无法创建子进程,或者无法检索其状态,则返回值为-1,并且将errno设置为指示错误。
*
如果无法在子进程中执行外壳程序,则返回值就好像子外壳程序通过调用状态为127的_exit(2)终止了。
*
如果所有系统调用均成功,则返回值是用于执行命令的子外壳的终止状态。 (shell的终止状态是它执行的最后一个命令的终止状态。)

在后两种情况下,返回值是"等待状态",可以使用waitpid(2)中描述的宏进行检查。 (即WIFEXITED(),WEXITSTATUS()等)。

system()不会影响其他任何孩子的等待状态。

SYSTEM - Linux手册页

Linux程序员手册 第3部分
更新日期: 2019-03-06

语法

#include <stdlib.h>

int system(const char *command);

错误说明

system()可能因与fork(2)相同的错误而失败。

备注

system()提供了简单和方便:它处理了调用fork(2),execl(3)和waitpid(2)的所有细节,以及对信号的必要操作;此外,shell对命令执行通常的替换和I / O重定向。 system()的主要成本是效率低下:需要额外的系统调用才能创建运行Shell的进程并执行Shell。

如果定义了_XOPEN_SOURCE功能测试宏(在包含任何头文件之前),则在包含时,将使waitpid(2)(WEXITSTATUS()等)中描述的宏可用。

如前所述,system()忽略SoirNT和SIGQUIT。这可能会使从循环调用它的程序不间断,除非他们自己注意检查孩子的退出状态。例如:

while (something) {
    int ret = system("foo");

    if (WIFSIGNALED(ret) &&
        (WTERMSIG(ret) == SoirNT || WTERMSIG(ret) == SIGQUIT))
            break;
}

根据POSIX.1,不确定在执行system()期间是否调用使用pthread_atfork(3)注册的处理程序。在glibc实现中,不会调用此类处理程序。

在2.1.3之前的glibc版本中,如果命令为NULL,则实际上不执行/ bin / sh可用性检查;而是始终假定它可用,并且在这种情况下system()始终返回1。从glibc 2.1.3开始,执行此检查是因为,即使POSIX.1-2001需要使用一致的实现来提供外壳程序,如果调用程序先前调用了chroot(2)( POSIX.1-2001未指定)。

shell命令可能会以状态127终止,这会产生与无法在子进程中执行shell的情况无法区分的system()返回值。

Caveats

不要使用特权程序(set-user-ID或set-group-ID程序或具有功能的程序)中的system(),因为某些环境变量的奇异值可能会用来破坏系统完整性。例如,可以对PATH进行操作,以便以特权执行任意程序。请改用exec(3)函数系列,而不要使用execlp(3)或execvp(3)(它们也使用PATH环境变量来搜索可执行文件)。

实际上,system()无法在/ bin / sh是bash版本2的系统上从具有set-user-ID或set-group-ID特权的程序正常工作:作为安全措施,bash 2在启动时放弃特权。 (Debian使用了另一个shell dash(1),当它作为sh调用时不会执行此操作。)

应该仔细清理用作命令一部分的任何用户输入,以确保不执行意外的Shell命令或命令选项。当使用特权程序中的system()时,此类风险尤其严重。

另外参见

sh(1),execve(2),fork(2),sigaction(2),sigprocmask(2),wait(2),exec(3),signal(7)

遵循规范

POSIX.1-2001,POSIX.1-2008,C89,C99。

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

名称

system-执行shell命令

说明

system()库函数使用fork(2)创建一个子进程,该子进程使用execl(3)执行命令中指定的shell命令,如下所示:

execl("/bin/sh", "sh", "-c", command, (char *) NULL);

命令完成后,system()返回。

在执行命令期间,在调用system()的过程中,SIGCHLD将被阻止,而SoirNT和SIGQUIT将被忽略。 (这些信号将在执行命令的子进程中根据其默认值进行处理。)

如果command为NULL,则system()返回一个状态,该状态指示shell在系统上是否可用。

日期:2019-08-20 18:01:29 来源:oir作者:oir