我是C的新手,我正在尝试创建一个简单的C shell,允许用户执行各种功能,如chdir,cd,exit,mkdir。
我在下面发布了我的代码。任何人都可以通过它看看我做错了什么?我不确定我是否正确使用fork
和execcv
。谢谢!
include stdio.h
include stdlib.h
include unistd.h
include <string.h>
include sys/types.h
main() {
//char *user;
//if ((user = getlogin()) == NULL)
// perror("__getlogin1() error");
//else printf("__getlogin1() returned %s\n", user);
int j, status;
int pid, c_pid;
int i = 0;
char *tmp, **ap;
char instring[80]; // store one line of input
char *argv[10]; // store parameters in the format for execv()
promptstart:
printf("Please enter a commcand:\n");
// read a char at a time and put it in instring[]
// put a '\0' at the end
instring[i] = getc(stdin); // stdin is the keyboard
while (instring[i] != '\n') {
i++;
instring[i] = getc(stdin);
}
instring[i] = '\0'; // replace '\n' with '\0'
tmp = instring;
i = 0;
argv[i] = strsep(&tmp, " \t"); // put first word int argv[0]
while ((i < 10) && (argv[i] != '\0')) {
i++;
argv[i] = strsep(&tmp, " \t");
}
// print out the command and options.
i = 0;
while (argv[i] != '\0') {
printf("your entered: %s\n", argv[i++]);
}
//PLACE ERROR HERE
if ((c_pid = fork()) == 0) {
for (j = 0; j < 10; j++)
printf("child (%d) prints %d\n", getpid(), j);
exit(0);
} else if (c_pid > 0) {
c_pid = wait(&status);
printf("child %d exited with status %d\n", c_pid, status);
} else {
execvp(argv[0], argv);
}
goto promptstart;
}
答案 0 :(得分:3)
至少IMO,你在main
投入了太多。我会从以下内容开始:
int main() {
char input[128];
do {
fgets(stdin, input, sizeof(input));
dispatch(input);
} while (strcmp(input, "exit"));
return 0;
}
然后dispatch
会查找内部命令,并且只有在{/ 1}}给出一个它无法识别的命令时才会执行exec
。为了简单起见,您可以考虑使用popen
执行外部命令,并在popen
的限制开始导致问题时,切换到“原始”fork / exec以供日后使用
答案 1 :(得分:0)
对于shell builtins(man bash
),你可能不想fork / exec。我会保存fork / exec来运行PATH中的程序(shell必须管理的环境变量)。 shell本身应该通过chdir
(man 2 chdir
)等命令与文件系统连接。
考虑使用一个好的字符串标记器(或者只是回退到strtok)来解析命令行,并且正如另一个注释所暗示的那样,将它抽象到一个函数中,以便你的主循环是精简的。