使用 fork 和 exec 的简单 shell
Simple shell with fork and exec
我正在尝试从 PATH 中创建一个简单的 shell 运行 任何命令,比如说 ls 或 pwd du gedit 等。我在使用 exec.I 时遇到了问题 require 如果我输入 space 没有任何反应,如果我输入退出它 terminates.Any 感谢帮助
#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] = '[=11=]';
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);
}
}
}
您有 2 个 fgets()
通话。去掉第一个fgets(line, BUFFER, stdin);
.
如果缓冲区中有 space,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;
}
您好,请看下面我的更正,也请看我的评论。
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
.
正确创建参数列表
我正在尝试从 PATH 中创建一个简单的 shell 运行 任何命令,比如说 ls 或 pwd du gedit 等。我在使用 exec.I 时遇到了问题 require 如果我输入 space 没有任何反应,如果我输入退出它 terminates.Any 感谢帮助
#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] = '[=11=]';
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);
}
}
}
您有 2 个
fgets()
通话。去掉第一个fgets(line, BUFFER, stdin);
.
如果缓冲区中有 space,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;
}
您好,请看下面我的更正,也请看我的评论。
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
.