我正在尝试创建一个简单的shell运行来自PATH的任何命令,让我们说ls或pwd du gedit等。我遇到exec.I要求如果我输入空间没有任何反应,如果我输入退出它终止。任何帮助表示赞赏
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#define BUFFER 1024
int main() {
char line[BUFFER];
char* args[100];
char* path = "";
char program[20];
while(1){
printf("$ ");
if(!fgets(line, BUFFER, stdin))
break;
size_t length = strlen(line);
if (line[length - 1] == '\n')
line[length - 1] = '\0';
if(strcmp(line, "exit")==0) break;
strcpy(program,path);
strcat(program,line);
int pid= fork(); //fork child
if(pid==0){ //Child
execlp(program,line,(char *)NULL);
}else{ //Parent
wait(NULL);
}
}
}
答案 0 :(得分:1)
嗨,请参阅下面的更正并查看我的评论。
int main() {
char line[BUFFER];
char* args[100];
char* path = "/bin/";
char program[20];
char command[50];
while(1){
printf("$ ");
if(!fgets(line, BUFFER, stdin))
break;
memset(command,0,sizeof(command));
if(strncmp(line, "exit", (strlen(line)-1))==0) break;
strncpy(command,line,(strlen(line)-1));
strcpy(program, path);
strcat(program,command);
int pid= fork(); //fork child
if(pid==0){ //Child
execl(program,command,NULL);
exit(0);// you must exit from the child because now you are inside while loop of child. Otherwise you have to type exit twice to exit from the application. Because your while loop also became the part of every child and from the child again it will call fork and create a child again
}else{
wait(NULL);
}
}
}
另外,为了支持所有命令执行,请参阅函数execl
如何传递参数。因此,您需要拆分命令并为execl
正确创建参数列表。
答案 1 :(得分:0)
您有2次fgets()
来电。删除第一个fgets(line, BUFFER, stdin);
。
fgets()
将在换行符中读取。您需要删除它,因为当您输入exit
时,您实际上输入exit\n
并且没有/bin/exit\n
的命令。
以下代码演示了删除换行符:
if(!fgets(line, BUFFER, stdin))
break;
char *p = strchr(line, '\n');
if (p) *p = 0;
execl
的手册。您需要传递参数:execl(program, line, (char *)NULL);
注意NULL
的最后一个参数的演员表。如果NULL
被定义为0
,那么强制转换是必要的,因为execl
是一个可变函数。使用execvp
的修改示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#define BUFFER 1024
int main(void) {
char line[BUFFER];
while(1) {
printf("$ ");
if(!fgets(line, BUFFER, stdin)) break;
char *p = strchr(line, '\n');
if (p) *p = 0;
if(strcmp(line, "exit")==0) break;
char *args[] = {line, (char*)0};
int pid= fork(); //fork child
if(pid==0) { //Child
execvp(line, args);
perror("exec");
exit(1);
} else { //Parent
wait(NULL);
}
}
return 0;
}