在C语言中运行命令行指令主要通过标准库函数实现,核心方法包括system()、exec()系列和popen(),以下是详细说明:
使用 system() 函数(简单执行命令)
功能:直接执行操作系统命令,阻塞当前进程直到命令完成。
示例代码:
int main() {
// 执行系统命令(Windows/Linux示例)
system("dir"); // Windows查看目录
system("ls -l"); // Linux查看目录
system("calc"); // 打开计算器
return 0;
}
特点:
- 跨平台(Windows/Linux均支持)
- 返回值:命令的退出状态码(成功通常返回0)
- 风险:直接拼接用户输入可能导致命令注入漏洞(如
system("rm " + user_input))
使用 exec() 系列函数(精细控制进程)
功能:替换当前进程为新的命令进程,需配合fork()使用。
常用函数:execl(), execv(), execvp()
示例代码(Linux):
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork(); // 创建子进程
if (pid == 0) { // 子进程
execl("/bin/ls", "ls", "-l", NULL); // 执行ls -l
} else { // 父进程
wait(NULL); // 等待子进程结束
}
return 0;
}
特点:
- 无命令注入风险(参数独立传递)
- 更高效(不启动额外shell)
- 仅Linux/Unix支持(Windows需用
CreateProcess)
使用 popen() 函数(获取命令输出)
功能:执行命令并捕获其输出结果。
示例代码:
#include <stdio.h>
int main() {
FILE *fp = popen("ls -l", "r"); // 执行命令并读输出
if (fp) {
char buffer[256];
while (fgets(buffer, sizeof(buffer), fp)) {
printf("%s", buffer); // 打印命令输出
}
pclose(fp); // 关闭管道
}
return 0;
}
特点:
- 通过管道(Pipe)交互数据
- 模式可选:
"r":读取命令输出"w":向命令输入数据
- 需及时
pclose()避免资源泄漏
关键注意事项
-
安全性:
- 避免直接拼接用户输入到
system()(如system(user_input))。 - 优先用
exec()或popen()分离参数。
- 避免直接拼接用户输入到
-
跨平台差异:
| 函数 | Windows支持 | Linux/Unix支持 |
|————|———————-|—————-|
|system()| ✓(调用cmd.exe) | ✓(调用/bin/sh) |
|exec()| ✗(需用CreateProcess) | ✓ |
|popen()| ✓ | ✓ | -
返回值处理:
system():返回命令退出状态码。popen():返回文件流指针,失败返回NULL。
应用场景建议
- 简单命令执行 →
system() - 需获取输出结果 →
popen() - 高性能/安全场景 →
exec()+fork()
引用说明参考自C11标准文档(ISO/IEC 9899:2011)、GNU Libc手册及Microsoft CRT文档,安全建议依据OWASP命令注入防护指南。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/9421.html