自定义system()函数运行异常求助:多命令仅执行一次、带参命令失效
解决自定义mySystem函数的两个问题
我来帮你分析下代码里的问题,以及对应的修复方案:
问题1:多次执行命令只跑一次
你的mySystem里直接调用了execlp,但**execlp会替换当前进程的整个地址空间**——也就是说,当第一个ls被执行时,你的a.out进程已经变成ls进程了,ls执行完毕后进程直接退出,根本不会回到main函数的循环里执行第二个ls。
解决办法是:用fork()创建子进程,在子进程里执行execlp,父进程等待子进程执行完毕后再继续循环。
问题2:带参数的命令执行异常
当你传入"ls -l"时,execlp会把整个字符串当作要执行的命令名,系统会去查找一个叫ls -l的可执行文件,这显然不存在,所以会执行失败。
正确的处理方式有两种:
- 方式一:模仿标准
system()函数的逻辑,调用/bin/sh -c来解析命令字符串,这样不管命令带多少参数都能正确处理; - 方式二:手动拆分命令字符串为命令名和参数列表,再传给
execlp(这种方式更复杂,适合需要精确控制参数的场景)。
这里推荐方式一,实现起来更简单,也和标准system()的行为一致。
修改后的完整代码
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> // 引入waitpid需要的头文件 void mySystem(char *command) { pid_t pid = fork(); if (pid == -1) { perror("fork failed"); return; } else if (pid == 0) { // 子进程:调用sh -c来执行命令,支持带参数的命令 execlp("/bin/sh", "sh", "-c", command, (char*)0); // 如果execlp返回,说明执行失败 perror("execlp failed"); exit(EXIT_FAILURE); } else { // 父进程:等待子进程执行完毕 int status; waitpid(pid, &status, 0); } } int main(int argc, char* argv[]) { for (int i = 1; i < argc; i++) { mySystem(argv[i]); } return 0; }
测试验证
- 执行
gcc exe6.c; ./a.out ls ls:现在会连续执行两次ls,因为每次调用mySystem都会创建子进程执行命令,父进程等待后回到循环继续执行下一个命令; - 执行
./a.out "ls -l":sh -c会正确解析ls -l,执行带参数的ls命令,正常输出长格式列表。
额外说明
标准system()函数还会处理信号等细节(比如忽略SIGINT、SIGQUIT),如果需要完全对齐标准行为,可以再补充信号处理的逻辑,但上面的代码已经解决了你当前遇到的两个核心问题。
内容的提问来源于stack exchange,提问作者Bruno
相关产品推荐
相关产品推荐

