在 C 中写一个 shell 我的程序无法退出()
writing a shell in C my program is not able to exit()
我正在编写一个程序来在 C 中实现一个简单的 shell
但是当我在最后执行程序时,当我键入 exit 时,它不会退出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#define BUFFER_LEN 1024
int main()
{
char line[BUFFER_LEN]; //get command line
char *argv[100]; //user command
char *path = "/bin/"; //set path at bin
char progpath[20]; //full file path
int argc; //arg count
while (1) {
printf("My shell>> "); //print shell prompt
if (!fgets(line, BUFFER_LEN, stdin)) { //get command and put it in line
size_t length = strlen(line);
if (line[length - 1] == '\n')
line[length - 1] = '[=11=]';
break; //if user hits CTRL+D break
}
if (strcmp(line, "exit") == 0) { //check if command is exit
exit(0);
break;
}
char *token; //split command into separate strings
token = strtok(line, " ");
int i = 0;
while (token != NULL) {
argv[i] = token;
token = strtok(NULL, " ");
i++;
}
argv[i] = NULL; //set last value to NULL for execvp
argc = i; //get arg count
for (i = 0; i < argc; i++) {
printf("%s\n", argv[i]); //print command/args
}
strcpy(progpath, path); //copy /bin/ to file path
strcat(progpath, argv[0]); //add program to path
for (i = 0; i < strlen(progpath); i++) { //delete newline
if (progpath[i] == '\n') {
progpath[i] = '[=11=]';
}
}
int pid = fork(); //fork child
if (pid == 0) { //Child
execvp(progpath, argv);
fprintf(stderr, "Child process could not do execvp\n");
} else { //Parent
wait(NULL);
printf("Child exited\n");
}
}
}
我在 cygwin 上执行因此生成 a.exe。
程序的执行
$ ./a.exe
My shell>> ls
ls
a.exe p3.4.cpp p3.6.cpp p3.6.cpp~ p3.7.cpp p3.7.cpp~ p3.cpp shell.c shell.c~ test.txt
Child exited
My shell>> cat test.txt
cat.txt
Child process could not do execvp
My shell>> exit
exit
Child process could not do execvp
My shell>> exit()
exit()
Child process could not do execvp
My shell>> exit
exit
Child process could not do execvp
My shell>> exit
exit
您可以在上面的输出中看到,当我在命令提示符下键入 exit 时,程序无法退出。我在上面的程序中犯了什么错误?
strcmp(line, "exit\n")==0
如果不包含换行符 (\n) 会怎样?
您可能将删除新行与处理 CTRL-D 混为一谈。您的代码
if (!fgets(line, BUFFER_LEN, stdin)) { //get command and put it in line
size_t length = strlen(line);
if (line[length - 1] == '\n')
line[length - 1] = '[=10=]';
break; //if user hits CTRL+D break
}
仅在 fgets
失败时才删除新行,例如已到达文件末尾。
此外,如果 length==0
.
,line[length-1]
将产生未定义的行为
我会替换逻辑:
if (!fgets(line, BUFFER_LEN, stdin)) { //get command and put it in line
break; //if user hits CTRL+D break
} else {
line[strcspn(line, "\n")] = '[=11=]';
}
我正在编写一个程序来在 C 中实现一个简单的 shell 但是当我在最后执行程序时,当我键入 exit 时,它不会退出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#define BUFFER_LEN 1024
int main()
{
char line[BUFFER_LEN]; //get command line
char *argv[100]; //user command
char *path = "/bin/"; //set path at bin
char progpath[20]; //full file path
int argc; //arg count
while (1) {
printf("My shell>> "); //print shell prompt
if (!fgets(line, BUFFER_LEN, stdin)) { //get command and put it in line
size_t length = strlen(line);
if (line[length - 1] == '\n')
line[length - 1] = '[=11=]';
break; //if user hits CTRL+D break
}
if (strcmp(line, "exit") == 0) { //check if command is exit
exit(0);
break;
}
char *token; //split command into separate strings
token = strtok(line, " ");
int i = 0;
while (token != NULL) {
argv[i] = token;
token = strtok(NULL, " ");
i++;
}
argv[i] = NULL; //set last value to NULL for execvp
argc = i; //get arg count
for (i = 0; i < argc; i++) {
printf("%s\n", argv[i]); //print command/args
}
strcpy(progpath, path); //copy /bin/ to file path
strcat(progpath, argv[0]); //add program to path
for (i = 0; i < strlen(progpath); i++) { //delete newline
if (progpath[i] == '\n') {
progpath[i] = '[=11=]';
}
}
int pid = fork(); //fork child
if (pid == 0) { //Child
execvp(progpath, argv);
fprintf(stderr, "Child process could not do execvp\n");
} else { //Parent
wait(NULL);
printf("Child exited\n");
}
}
}
我在 cygwin 上执行因此生成 a.exe。
程序的执行
$ ./a.exe
My shell>> ls
ls
a.exe p3.4.cpp p3.6.cpp p3.6.cpp~ p3.7.cpp p3.7.cpp~ p3.cpp shell.c shell.c~ test.txt
Child exited
My shell>> cat test.txt
cat.txt
Child process could not do execvp
My shell>> exit
exit
Child process could not do execvp
My shell>> exit()
exit()
Child process could not do execvp
My shell>> exit
exit
Child process could not do execvp
My shell>> exit
exit
您可以在上面的输出中看到,当我在命令提示符下键入 exit 时,程序无法退出。我在上面的程序中犯了什么错误?
strcmp(line, "exit\n")==0
如果不包含换行符 (\n) 会怎样?
您可能将删除新行与处理 CTRL-D 混为一谈。您的代码
if (!fgets(line, BUFFER_LEN, stdin)) { //get command and put it in line
size_t length = strlen(line);
if (line[length - 1] == '\n')
line[length - 1] = '[=10=]';
break; //if user hits CTRL+D break
}
仅在 fgets
失败时才删除新行,例如已到达文件末尾。
此外,如果 length==0
.
line[length-1]
将产生未定义的行为
我会替换逻辑:
if (!fgets(line, BUFFER_LEN, stdin)) { //get command and put it in line
break; //if user hits CTRL+D break
} else {
line[strcspn(line, "\n")] = '[=11=]';
}