system() 和 popen() 是 C 语言中用于执行外部命令的两个函数,它们的功能类似,但在使用方式和特性上有一些区别。
system()
system() 函数允许您在程序中执行外部命令,并等待该命令执行完成后继续执行程序。其基本语法如下:
int system(const char *command);
-  command是一个字符串,包含您要执行的命令。这可以是任何有效的命令,就像您在命令行中输入的一样。
-  system()函数将返回执行结果。如果成功执行了命令,则返回值为命令的退出状态码。如果无法执行命令,则返回 -1。
-  system()函数会阻塞当前进程,直到执行的命令完成。
示例:
#include <stdio.h>
#include <stdlib.h>
int main() {
    int status = system("ls -l");
    if (status == -1) {
        printf("Failed to execute command\n");
    } else {
        printf("Command executed successfully with exit status: %d\n", status);
    }
    return 0;
}
执行结果:

popen()
popen() 函数允许您在程序中执行外部命令,并建立一个到该命令的管道,可以通过管道进行输入和输出。其基本语法如下:
-  command和mode参数分别与system()函数的参数相同,用于指定要执行的命令和管道的打开模式。
-  popen()函数返回一个指向 FILE 结构的指针,您可以使用该指针来读取或写入命令的输入和输出。
-  popen()函数允许并发执行多个命令,并且可以通过管道进行通信。
示例:
#include <stdio.h>
int main() {
    FILE *fp;
    char buffer[1024];
    fp = popen("ls -l", "r");
    if (fp == NULL) {
        printf("Failed to execute command\n");
        return 1;
    }
    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
        printf("%s", buffer);
    }
    pclose(fp);
    return 0;
}
执行结果:

这段代码的作用是执行一个外部命令 ls -l(列出当前目录下的文件和文件夹,并显示详细信息),并将命令的输出逐行打印到标准输出(终端)上。
让我们逐行解释代码:
-  #include <stdio.h>:包含了标准输入输出的头文件。
-  int main():主函数的定义。
-  FILE *fp;:声明了一个指向FILE结构的指针fp,它将被用作popen()返回的管道。
-  char buffer[1024];:声明了一个用于存储命令输出的缓冲区。
-  fp = popen("ls -l", "r");:调用popen()函数执行外部命令ls -l,并将其输出连接到管道上。模式"r"表示只读模式,因此fp将用于从管道读取命令的输出。
-  if (fp == NULL):检查popen()函数的返回值,如果返回空指针,则表示执行命令失败。
-  printf("Failed to execute command\n");:打印错误信息。
-  return 1;:退出程序,返回错误代码。
-  while (fgets(buffer, sizeof(buffer), fp) != NULL):使用fgets()函数从管道中读取命令的输出,并将其逐行存储到buffer缓冲区中。循环会继续,直到fgets()函数返回NULL,表示已经读取完全部输出。
-  printf("%s", buffer);:打印缓冲区中的内容,即命令的输出。
-  pclose(fp);:关闭由popen()打开的管道,并等待命令执行完毕。
-  return 0;:退出程序,返回成功代码。
system 和 popen的区别:
-  返回类型: - system()返回命令的退出状态码。
- popen()返回一个文件指针,用于读取或写入命令的输入和输出。
 
-  阻塞特性: - system()函数会阻塞当前进程,直到执行的命令完成。
- popen()函数允许并发执行多个命令,并且您可以在不等待命令完成的情况下继续执行程序。
 
-  输入输出: - system()函数只能捕获命令的退出状态码,无法直接获取命令的输入和输出。
- popen()函数可以通过管道进行输入和输出,允许更灵活的交互。
 
综上所述,如果您只需要执行简单的命令并等待其完成,可以使用 system() 函数。如果您需要与命令进行交互,或者需要同时执行多个命令,可以使用 popen() 函数。
问:是不是虽然没有ls -l的运行结果没在终端显示,但是它已经执行了?
        是的,即使没有使用 printf 或其他输出函数将 popen() 命令的输出显示在终端上,该命令仍然会在后台执行,并将结果写入到管道中。
        即便没有读取管道中的输出,popen() 也会执行给定的命令,并等待命令执行完成。只是程序没有处理这些输出而已。



















