📅  最后修改于: 2023-12-03 15:00:12.297000             🧑  作者: Mango
有时候,我们需要在C程序中执行一些Shell命令,比如执行系统命令,调用外部程序等等。C语言提供了一些函数和库来完成这个任务,本文将简单介绍如何在C程序中执行Shell命令。
system()
是在C程序中执行Shell命令最简单的方法,其原型为:
int system(const char *command);
它接收一个字符串参数 command
,表示要执行的Shell命令。system()
函数将阻塞程序执行直到Shell命令完成,并返回Shell命令的退出码。
下面是一个简单的例子:
#include <stdlib.h>
int main(void)
{
system("ls -alh");
return 0;
}
上面的代码会执行 ls -alh
命令,列出当前目录下所有的文件和目录。
注意:使用 system()
函数执行Shell命令可能存在安全问题,因为传递给 system()
函数的字符串参数实际上是一个可以被用户输入的命令,如果不小心传入了恶意命令,可能会导致系统安全问题。因此,最好不要将用户输入直接传入 system()
函数中。如果必须这么做,可以对用户输入进行严格的过滤,或者使用更安全的函数。
popen()
函数也可以执行Shell命令,并且不同于 system()
函数的阻塞,popen()
可以在C程序中创建一个Shell进程并在其上下文中执行命令。其原型为:
FILE *popen(const char *command, const char *mode);
popen()
函数接收两个参数:第一个参数 command
表示要执行的Shell命令,第二个参数 mode
表示打开流的模式,可以是 "r"
(只读)或 "w"
(只写)。popen()
函数返回一个指向流的指针,该流可以读取或写入到Shell进程的标准输出或标准输入。
下面是一个简单的例子:
#include <stdio.h>
#define BUFSIZE 1024
int main(void)
{
char buf[BUFSIZE];
FILE *fp;
fp = popen("ls -alh", "r");
if (fp == NULL) {
perror("popen error");
return -1;
}
while (fgets(buf, BUFSIZE-1, fp) != NULL) {
printf("%s", buf);
}
pclose(fp);
return 0;
}
上面的代码使用 popen()
函数执行 ls -alh
命令,并读取Shell进程的标准输出。使用 fclose()
函数关闭流,并等待Shell进程结束。
使用 popen()
函数同样需要注意安全问题。
exec()
函数族是C程序中执行Shell命令的更底层的方法。exec()
函数实际上是一组函数,包括 execl()
、execle()
、execlp()
、execv()
、execve()
、execvp()
等。这些函数会在进程中执行新的程序,取代原有的进程映像。因此,exec()
函数族执行后不会返回到原来的程序,除非出现错误。
这里只介绍其中的两个常用函数:execl()
和 execvp()
。
execl()
函数可以执行指定路径的Shell命令,其原型为:
int execl(const char *path, const char *arg0, const char *arg1, ..., (char *)0);
execl()
函数接收任意多个字符串参数,其中,第一个参数 path
是要执行的Shell命令的完整路径,后面的参数是Shell命令的参数,用空格分隔。最后一个参数必须是空指针。
下面是一个简单的例子:
#include <unistd.h>
int main(void)
{
int ret;
ret = execl("/bin/ls", "ls", "-alh", NULL);
if (ret < 0) {
perror("execl error");
return -1;
}
return 0;
}
上面的代码使用 execl()
函数执行 /bin/ls -alh
命令。
execvp()
函数与 execl()
函数用法差不多,其原型为:
int execvp(const char *file, char *const argv[]);
execvp()
函数接收两个参数:第一个参数 file
表示要执行的Shell命令的路径,第二个参数 argv
是一个字符串数组,每个元素表示Shell命令的参数,字符串数组的最后一个元素必须是空指针。
下面是一个简单的例子:
#include <unistd.h>
int main(void)
{
char *argv[4] = {"ls", "-alh", "/tmp", NULL};
int ret;
ret = execvp("ls", argv);
if (ret < 0) {
perror("execvp error");
return -1;
}
return 0;
}
上面的代码使用 execvp()
函数执行 ls -alh /tmp
命令。
注意:使用 exec()
函数族执行Shell命令需要注意参数的安全性,尤其是在程序员需要在运行时指定参数时更容易出现问题。因此,必须严格检查参数,以避免安全漏洞。