为什么我的 C shell 没有输出任何东西?
Why isn't my C shell outputting anything?
正在为 class 做一个项目。我们应该写一个 C shell。我找到了很多很好的例子,但对于我来说,我无法让我的版本生成任何输出。
它一直在打印提示,但没有别的。
我已经按照一些近乎逐字的示例尝试解决此问题,但仍然一无所获。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <sys/wait.h>
/******************************************
@brief Fork a child to execute the command using execvp. The parent should wait for the child to terminate
@param args Null terminated list of arguments (including program).
@return returns 1, to continue execution and 0 to terminate the MyShell prompt.
******************************************/
int execute(char **args)
{
pid_t pid;
int status;
if ((pid = fork()) < 0)
{
printf("*** ERROR: forking child process failed\n");
exit(1);
}
else if (pid == 0)
{
if (execvp(*args, args) < 0) {
printf("*** ERROR: exec failed\n");
exit(1);
}
}
else
{
while (wait(&status) != pid)
;
}
return 0;
}
/******************************************
@brief gets the input from the prompt and splits it into tokens. Prepares the arguments for execvp
@return returns char** args to be used by execvp
******************************************/
char** parse(void)
{
//Get the string and store it. Remove newline.
char strIn[255];
printf("MyShell>");
fgets(strIn, sizeof(strIn), stdin);
strIn[strlen(strIn)-1]='[=11=]';
//Array, token, counters.
char *args[20];
char *tok;
int i = 0;
int count = 0;
//Allocate array.
for(i = 0; i < 20; i++)
{
args[i] = (char*)malloc(20 * sizeof(char));
}
//Fill in args[0]
tok = strtok(strIn, " ");
strcpy(args[count++], tok);
//Fill in array with tokens.
while (tok != NULL)
{
tok = strtok(NULL, " ");
if (tok == NULL)
break;
strcpy(args[count++], tok);
}
//Null terminate.
args[count] = NULL;
return args;
}
/******************************************
@brief Main function should run infinitely until terminated manually using CTRL+C or typing in the exit command
It should call the parse() and execute() functions
@param argc Argument count.
@param argv Argument vector.
@return status code
******************************************/
int main(int argc, char **argv)
{
bool run = true;
while(run)
{
char** argArr = parse();
execute(argArr);
}
return 0;
}
无论我做什么,输出都是:
MyShell>
MyShell>
MyShell>
谁能告诉我哪里做错了?
parse()
return 是指向本地数组 args
的指针。由于 args
的生命周期在 parse()
return 秒时结束,因此任何使用 parse()
的 return 值的尝试都是未定义的行为。您应该使用 malloc()
分配该数组(稍后释放它!)。
在我的测试中发生的事情是编译器注意到 parse()
的 return 值不能合法使用 (and it gives a warning!! which you should read and pay attention to!!),所以它只是 returns NULL
代替。当 child 将此指针取消引用为 *args
以获取 execvp
的第一个参数时,它会发生段错误并在未调用 execvp()
的情况下终止。如果您检查了 wait()
编辑的 status
return,您可以检测到这一点,但您没有。所以它看起来好像 child 没有做任何事情。
哦,额外的错误:当 end-of-file 出现在 stdin
上时(例如,如果您点击 Ctrl-D),由 fgets()
编辑的字符串 return 将为空并且 strIn[strlen(strIn)-1]='[=25=]';
将存储一个越界的空字节。您需要测试 fgets()
的 return 值。
正在为 class 做一个项目。我们应该写一个 C shell。我找到了很多很好的例子,但对于我来说,我无法让我的版本生成任何输出。
它一直在打印提示,但没有别的。
我已经按照一些近乎逐字的示例尝试解决此问题,但仍然一无所获。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <sys/wait.h>
/******************************************
@brief Fork a child to execute the command using execvp. The parent should wait for the child to terminate
@param args Null terminated list of arguments (including program).
@return returns 1, to continue execution and 0 to terminate the MyShell prompt.
******************************************/
int execute(char **args)
{
pid_t pid;
int status;
if ((pid = fork()) < 0)
{
printf("*** ERROR: forking child process failed\n");
exit(1);
}
else if (pid == 0)
{
if (execvp(*args, args) < 0) {
printf("*** ERROR: exec failed\n");
exit(1);
}
}
else
{
while (wait(&status) != pid)
;
}
return 0;
}
/******************************************
@brief gets the input from the prompt and splits it into tokens. Prepares the arguments for execvp
@return returns char** args to be used by execvp
******************************************/
char** parse(void)
{
//Get the string and store it. Remove newline.
char strIn[255];
printf("MyShell>");
fgets(strIn, sizeof(strIn), stdin);
strIn[strlen(strIn)-1]='[=11=]';
//Array, token, counters.
char *args[20];
char *tok;
int i = 0;
int count = 0;
//Allocate array.
for(i = 0; i < 20; i++)
{
args[i] = (char*)malloc(20 * sizeof(char));
}
//Fill in args[0]
tok = strtok(strIn, " ");
strcpy(args[count++], tok);
//Fill in array with tokens.
while (tok != NULL)
{
tok = strtok(NULL, " ");
if (tok == NULL)
break;
strcpy(args[count++], tok);
}
//Null terminate.
args[count] = NULL;
return args;
}
/******************************************
@brief Main function should run infinitely until terminated manually using CTRL+C or typing in the exit command
It should call the parse() and execute() functions
@param argc Argument count.
@param argv Argument vector.
@return status code
******************************************/
int main(int argc, char **argv)
{
bool run = true;
while(run)
{
char** argArr = parse();
execute(argArr);
}
return 0;
}
无论我做什么,输出都是:
MyShell>
MyShell>
MyShell>
谁能告诉我哪里做错了?
parse()
return 是指向本地数组 args
的指针。由于 args
的生命周期在 parse()
return 秒时结束,因此任何使用 parse()
的 return 值的尝试都是未定义的行为。您应该使用 malloc()
分配该数组(稍后释放它!)。
在我的测试中发生的事情是编译器注意到 parse()
的 return 值不能合法使用 (and it gives a warning!! which you should read and pay attention to!!),所以它只是 returns NULL
代替。当 child 将此指针取消引用为 *args
以获取 execvp
的第一个参数时,它会发生段错误并在未调用 execvp()
的情况下终止。如果您检查了 wait()
编辑的 status
return,您可以检测到这一点,但您没有。所以它看起来好像 child 没有做任何事情。
哦,额外的错误:当 end-of-file 出现在 stdin
上时(例如,如果您点击 Ctrl-D),由 fgets()
编辑的字符串 return 将为空并且 strIn[strlen(strIn)-1]='[=25=]';
将存储一个越界的空字节。您需要测试 fgets()
的 return 值。