我想先说我是 C 的新手,因此对它很糟糕,所以我提前为任何明显的错误或糟糕的风格道歉。另外,在向您展示我的代码之前,我不确定如何介绍问题,所以这里是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int MAX_INPUT_SIZE = 200;
volatile int running = 1;
while (running)
{
char input[MAX_INPUT_SIZE];
char *tokens[100];
const char *cmds[] = { "wait", "pwd", "cd", "exit" };
char *cmdargs[100];
printf("shell> ");
fgets(input, MAX_INPUT_SIZE, stdin);
// remove newline character at end
int nl = strlen(input) - 1;
if (input[nl] == '\n')
{
input[nl] = '\0';
}
// tokenize input string, put each token into an array
char *space;
space = strtok(input, " ");
tokens[0] = space;
int i = 1;
while (space != NULL)
{
space = strtok(NULL, " ");
tokens[i] = space;
++i;
}
// copy tokens after first one into string
int noargscheck;
if (tokens[1] != NULL)
{
noargscheck = 0;
strcpy((char *)cmdargs, tokens[1]);
for (i = 2; tokens[i] != NULL; i++)
{
strcat((char *)cmdargs, " ");
strcat((char *)cmdargs, tokens[i]);
}
}
else
{
noargscheck = 1;
}
// compare tokens[0] to list of internal commands
int isInternal = -1;
for (i = 0; i < 4; i++)
{
if (strcmp(tokens[0], cmds[i]) == 0)
{
isInternal = i;
}
}
// internal commands
char wd[200];
if (isInternal != -1)
{
switch (isInternal)
{
case 0:
// wait
break;
case 1:
// pwd
if (getcwd(wd, sizeof(wd)) == NULL)
{
perror("getcwd() error!");
}
else
{
printf("%s\n", wd);
}
break;
case 2:
// cd
if (noargscheck)
{
chdir("/home");
}
else if (chdir((const char *)cmdargs) != 0)
{
perror("cd failed");
}
break;
case 3:
// exit
exit(1);
break;
}
}
else
{
// external commands
pid_t child_pid;
switch (child_pid = fork())
{
case -1:
perror("Fork failed");
return 1;
case 0:
// child
printf("\nHERE\n"); // for debugging
execvp(tokens[0], cmdargs);
break;
}
}
}
}
当我使用 input 运行此代码时echo hello world
,程序成功地case 0
在第二个 switch 语句中输入了 case,switch (child_pid=fork())
但输出是意外的,如下所示:
输出:(包括在提示符下显示我输入的一行)
shell> echo hello world
(我的输入)
shell>
(这是我不明白的部分)
HERE
shell>
(程序现在在提示下等待下一个用户输入)
我无法弄清楚为什么要shell>
打印额外的提示。任何人都可以看到问题吗?
编辑:修复了 execvp 的第一个参数。从"echo"
(因为我很傻所以在那里)更改为tokens[0]
.