【发布时间】:2015-04-14 15:42:43
【问题描述】:
我必须使用系统调用 fork()/execvp() 用 C 语言开发一个简单的 shell。到目前为止,我的代码接受了一个命令,使用 strtok 将其拆分为一个数组 argv,然后我调用 fork 创建一个子进程并执行该命令。我在 ubuntu 中处理这个问题,其中大多数命令都在 /bin/ 目录中,所以我附加程序名称(例如 /bin/ls)并将其用于 execvp 的第一个 arg,然后我给它 argv 数组.如果我输入命令“ls”,我的程序就可以工作,但是当尝试其他命令甚至“ls -l”时,我得到一个“ls:无效选项”。我不确定我在这里做错了什么。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_LEN 1024
int main(){
char line[BUFFER_LEN]; //get command line
char* argv[100]; //user command
char* path= "/bin/"; //set path at bin
char progpath[20]; //full file path
int argc; //arg count
while(1){
printf("My shell>> "); //print shell prompt
if(!fgets(line, BUFFER_LEN, stdin)){ //get command and put it in line
break; //if user hits CTRL+D break
}
if(strcmp(line, "exit\n")==0){ //check if command is exit
break;
}
char *token; //split command into separate strings
token = strtok(line," ");
int i=0;
while(token!=NULL){
argv[i]=token;
token = strtok(NULL," ");
i++;
}
argv[i]=NULL; //set last value to NULL for execvp
argc=i; //get arg count
for(i=0; i<argc; i++){
printf("%s\n", argv[i]); //print command/args
}
strcpy(progpath, path); //copy /bin/ to file path
strcat(progpath, argv[0]); //add program to path
for(i=0; i<strlen(progpath); i++){ //delete newline
if(progpath[i]=='\n'){
progpath[i]='\0';
}
}
int pid= fork(); //fork child
if(pid==0){ //Child
execvp(progpath,argv);
fprintf(stderr, "Child process could not do execvp\n");
}else{ //Parent
wait(NULL);
printf("Child exited\n");
}
}
}
【问题讨论】:
-
除非您的 PATH 环境变量不包含
/bin,否则您不需要将/bin附加到文件名。另外,这是不安全的,可能与问题无关,但不安全while(token!=NULL)使其成为while(token!=NULL && i < 100)