📜  system() 和 execl() 调用之间的区别(1)

📅  最后修改于: 2023-12-03 14:47:49.849000             🧑  作者: Mango

system() 和 execl() 调用之间的区别

在Linux环境中,程序员可以使用system()和execl()来运行一个新的进程。这两个函数都可以在新的进程中运行一个可执行文件,但是二者还是有很多区别的。下面详细介绍一下system()和execl()调用之间的区别。

system()

system()函数用于在当前进程中运行命令行。该函数的原型如下:

#include <stdlib.h>

int system(const char *command);

其中,command参数是要执行的命令行字符串。system()函数将创建一个新的进程,执行指定的命令,等待命令执行完毕,然后返回控制到主程序中。

system()函数的返回值有两种情况:

  • 如果命令行字符串为NULL,则返回非零值,表示系统调用失败。
  • 如果命令行字符串不为NULL,则返回命令行执行完成后的退出状态码。如果命令行运行成功,则返回0;如果运行失败,则返回非零值。

system()函数具有以下特性:

  • 执行命令行的子进程由system()函数创建。在子进程中,命令行的执行由shell程序处理。
  • system()函数会等待子进程执行完成后,再将控制返回到主程序中。
  • system()函数返回的值表示子进程的运行状态,即为命令行执行的退出状态码。
execl()

execl()函数用于在当前进程中执行指定的可执行文件。该函数的原型如下:

#include <unistd.h>

int execl(const char *path, const char *arg0, ... /*, (char *)0 */);

其中,path参数是可执行文件路径,arg0是程序名,剩下的参数列表是附加到程序中的命令行参数。

execl()函数将当前进程所在的地址空间全部替换成指定的可执行文件。程序会从指定的文件的第一行开始执行,并将附加的命令行参数传递给可执行文件。

execl()函数的返回值有两种情况:

  • 如果执行成功,则execl()函数并不返回任何值,因为当前进程的地址空间已经被替换成新的可执行文件了。
  • 如果执行失败,则返回-1,并设置errno为相应的错误码。

execl()函数具有以下特性:

  • 执行程序的地址空间会被完全替换,当前进程的状态和数据都会被删除。因此,execl()函数在当前进程中调用后完毕之后,程序就停止运行了。
  • execl()函数不会创建新的进程,而是直接用指定的可执行文件替换当前进程,变成了一个新的进程。
  • 由于execl()函数不创建新的进程,也不会创建shell环境,因此在程序中执行的命令不能包含环境变量。
总结

两个函数的区别可以总结如下:

  • system()可以执行shell脚本,execl()不能。
  • system()会创建子进程,execl()不会。
  • system()的命令行是由shell程序处理的,execl()的命令行是直接传递给可执行文件。
  • system()只能获取命令的退出码,execl()无法获取命令的退出码,因为当前进程已经被替换成新的可执行文件。