我正在使用 C 语言开发一个非常基本的 UNIX shell。在这个项目中,我尝试使用fork()
并execvp()
执行实际的 shell 命令。不过,我遇到了一个问题,它似乎可以与具有单个参数的命令一起正常工作(例如ls -l
并且echo howareyoutoday
工作完美),但具有多个参数的命令无法执行(echo how are you today
不运行)。我将向您介绍我的代码/基本原理,以帮助您找到此问题背后的原因。
char *token;
int count=0;
pid_t childProc;
int childStatus;
pid_t tpid;
char* argv[256];
int i=1;
childProc = fork();
if (childProc==0) {
//CHILD PROCESS IS HERE
argv[0] = malloc(strlen(token));
argv[0] = token;
token=strtok(NULL," \n\t()<>|&;");
while(token!=NULL) {
argv[i]=malloc(strlen(token));
argv[i]=token;
token=strtok(NULL," \n\t()<>|&;");
i++;
}
execvp(argv[0],argv);
//if this executes execvp fails
printf("failure to execute\n");
i=0;
exit(0);
}
else {
//PARENT PROCESS IS HERE
do {
tpid = wait(&childStatus);
} while(tpid != childProc);
}
因此,它从fork()
创建子进程的基本调用开始。在那个子进程中,我为argv
数组中的第一个元素分配内存。token
来自先前strtok
调用的分配给argv[0]
. 生成一个新元素token
并将其添加到下一个argv
元素。对剩余的令牌重复此过程。
一旦argv
数组完成,execvp
就会调用,第一个参数包含命令名称,第二个参数是整个argv
数组。如果命令执行失败,execvp
将返回并打印一条消息表明这一点。
我无法弄清楚为什么我会遇到上面提到的多个参数问题。任何帮助或建议将不胜感激!
作为参考,完整程序的代码如下:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char buffer[256];
char *token;
int count=0;
pid_t childProc;
int childStatus;
pid_t tpid;
char* argv[256];
int i=1;
int j=0;
while(1) {
fgets(buffer, 256, stdin);
token=strtok(buffer," \n\t()<>|&;");
while (token==NULL) {
fgets(buffer,256,stdin);
token=strtok(buffer," \n\t()<>|&;");
}
if (strcmp(token,"exit")==0) {
exit(0);
}
else if (strcmp(token,"cd")==0) {
token = strtok(NULL, " \n\t()<>|&;");
if (chdir(token)!=0) {
perror("Error: ");
}
}
else {
childProc = fork();
if (childProc==0) {
argv[0] = malloc(strlen(token));
argv[0] = token;
token=strtok(NULL," \n\t()<>|&;");
while(token!=NULL) {
argv[i]=malloc(strlen(token));
argv[i]=token;
token=strtok(NULL," \n\t()<>|&;");
i++;
}
execvp(argv[0],argv);
//if this executes execvp fails
printf("failure to execute\n");
i=0;
exit(0);
}
else {
do {
tpid = wait(&childStatus);
} while(tpid != childProc);
}
}
}
}