使用通配符作为参数运行C程序时仅列出首个文件的问题排查
你的while循环条件没问题,但问题出在
execl的工作机制上! 首先直接给结论:while的条件完全正确,导致只处理第一个文件的元凶是execl函数本身的特性。
为什么会这样?
当你调用execl时,它会用新的程序(这里是/bin/ls)完全替换当前进程的内存空间、代码和数据——也就是说,一旦execl成功执行,你的原程序(包括a++和后续的循环逻辑)就彻底消失了,不会再继续运行。所以第一次循环执行execl后,你的程序就变成了ls,执行完就直接退出了,根本没机会走到a++和下一次循环。
怎么解决?
如果你想循环处理每个参数并执行ls,需要为每个execl调用创建一个子进程,让子进程去执行ls,父进程继续完成循环。修改后的代码大概是这样:
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main(int argc, char *argv[]) { int a=1; while(argv[a] != NULL) { printf("\nargv[a] = %s\n", argv[a]); pid_t pid = fork(); if (pid == 0) { // 子进程:执行ls execl("/bin/ls", "ls", argv[a], NULL); // 如果execl执行失败才会走到这里 perror("execl failed"); _exit(1); } else if (pid > 0) { // 父进程:等待子进程执行完毕,再继续循环 wait(NULL); } else { perror("fork failed"); return 1; } a++; } return 0; }
补充说明
- 如果你不想手动处理fork,也可以考虑用
system函数(不过它会调用shell,安全性稍差),或者用execvp(更灵活的exec系列函数),但核心思路都是不要让exec系列函数替换掉你的主循环进程。 - 另外,shell在执行
./code ../input/*.lot时,会先把*.lot展开成三个具体的文件名,所以你的程序确实能拿到三个参数,这点是没问题的。
内容的提问来源于stack exchange,提问作者Sergio
相关产品推荐
相关产品推荐

