学校项目制作我们自己的shell并面临分段故障问题。 有人可以帮忙吗?
编辑:运行类型,但“退出”不会触发退出并且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 */
;
}
}
请帮帮忙?
答案 0 :(得分:0)
您是否尝试打印所有变量argv
,str
,commands
...以确保所有变量按预期进行?它还可以帮助您在脚本中找到段错误的位置。这会花费你的时间,抱歉,我没有快速回答。对于启动器printf("%d", __LINE__)
,将打印您所在的行号,不要忘记添加明确的声明。
否则你可以使用gdb。有一个学习曲线,但它可能对另一个项目有用。