【发布时间】:2017-02-28 18:22:38
【问题描述】:
制作我们自己的外壳并面临分段错误问题的学校项目。 有人可以帮忙吗?
编辑:某种运行但“退出”不会触发退出并且 execvp 无法正常运行(说:“没有这样的文件或目录”&“或 ls:invalid option -- '”
void interactive_mode();
void batch_mode(char *path);
void parse(char *str,char *delimeter,char **args);
int execute(char **args);
int main(int argc, char *argv[]){
if(strcmp(argv[1],"-b")==0){
batch_mode(argv[2]);
}
else if(strcmp(argv[1],"-i")==0){
interactive_mode();
}
}
我怀疑分段错误问题源于交互式 和批处理模式代码
void interactive_mode(){
int quit_flag;
char str[512];
char *commands[128];
char *args[128];
quit_flag=0;
while(1){
printf("whatever> ");
if(fgets(str,512,stdin)==NULL){
exit(0); //error reading
}
int i=0;
parse(str,";",commands); //split the string into commands eg "ls -a ; ls -l" -> "ls -a ","ls -l"
while(commands[i]!=NULL){
parse(commands[i]," ",args); //split commands into arguements eg "ls -l" -> "ls","-l"
i++;
quit_flag=execute(args);
}
if(quit_flag==1) exit(1);
}
}
// 试图从文件中读取
void batch_mode(char *path){
FILE *fp;
char str[512];
char *commands[128];
char *args[128];
int res;
fp=fopen(path,"r");
if(fp==NULL){
perror("Error opening file");
exit(4); //file not open
}
while(1){
if(fgets(str,512,fp)==NULL) break;
int i=0;
parse(str,";",commands);
while(commands[i]!=NULL){
parse(commands[i]," ",args);
i++;
res=execute(args);
}
}
fclose(fp);
printf("whatever>Press Any Key to Continue\n");
getchar();
}
//解析字符串
void parse(char *str,char *delimeter,char **args){
char *pch;
int i=0;
pch=strtok(str,delimeter);
while(pch!=NULL){
args[i]=pch;
i++;
pch=strtok(NULL,delimeter);
}
args[i]=NULL;
}
// 使用 fork 执行
int execute(char **args){
char path[50];
pid_t pid;
int status;
if(strcmp(args[0],"quit")==0) return 1; //exited by quit
strcpy(path,"/bin/");
strcat(path,args[0]);
if ((pid=fork())<0){
perror("fork failed");
exit(2);
}
else if (pid==0){
if(execvp(path,args)<0){
perror("execvp failed");
exit(3);
}
}
else{
while (wait(&status) != pid) /* wait for completion */
;
}
}
请帮忙?
【问题讨论】:
-
parse需要pch=strtok(NULL,delimeter);在 while 循环结束时。 (需要更新pch) -
当您在没有任何命令行参数的情况下调用 shell 时,您的
strcmp()调用具有未定义的行为。他们很可能会出现段错误。您应该使用argc来确定是否有要测试的命令行参数。 -
如果您使用
-b选项但没有文件名参数调用它,则类似。 -
在没有首先检查
argc以确保命令行参数确实存在之前,不要访问argv[0]以外的地方。如果预期的命令行参数不存在,输出一条 USAGE 消息到 stderr 然后调用exit( EXIT_FAILURE ); -
为了便于阅读和理解,1) 请一致地缩进代码:在每个左大括号'{'之后缩进,在每个右大括号'}'之前不缩进。建议每个缩进级别使用 4 个空格。 2) 遵循公理:每行只有一个语句,并且(最多)每条语句有一个变量声明。
标签: c shell segmentation-fault