我正在为C中的赋值编写一个shell。我现在唯一的问题是,当我使用execvp()调用外部程序然后关闭使用CTRL + C时,我发送的任何其他命令都会在提示符后打印出来不是在它之前。我做了一个虚拟程序,只是一个无限循环来测试它。
关闭此程序后,如果我尝试运行一个不存在的程序,它将打印出来 MINISHELL(cwd)$:然后是一个空白行 然后它将打印我的错误消息,说我已经输入了一个不存在的程序,然后它不会打印提示,因为它已经有了。所以它以一个空的新行结束,看起来该程序还没有结束但实际上已经结束了。
仅在用CTRL + C关闭非终止程序后才执行此操作。否则它可以正常执行程序。我是不是在某处使用close()来关闭文件描述符?我不确定。任何帮助表示赞赏。谢谢。
#include "minishell.h"
void intHandler(int sig)
{
my_char('\n');
}
int main(int argc, char **argv)
{
int n;
int pid = 0;
char* s = (char*)malloc(256*sizeof(char));
char cwd[1024];
char** input;
while (1)
{
signal(SIGINT, intHandler);
my_str("MINISHELL:");
if (getcwd(cwd, sizeof(cwd)) != NULL)
my_str(cwd);
else
{
my_str("Error in current directory");
return -1;
}
my_str(" $: ");
n = read(0, s, 256);
s[n] = '\0';
if (n > 1)
{
input = my_str2vect(s);
if (my_strcmp(input[0], "cd") == 0)
{
/*CHANGE DIRECTORY*/
if (input[1] != '\0')
{
if (chdir(input[1]) < 0)
my_str("MINISHELL: Error in path. Make sure the directory exists.\n");
}
else
my_str("MINISHELL: Error. No directory specified.\n");
}
else if (my_strcmp(input[0], "help") == 0)
{
/*HELP*/
my_str("\nMINISHELL COMMANDS:\n\ncd *directory\nChanges the current working directory to *directory\n\nexit\nExits the minishell\n\nhelp\nPrints a help message listing the built in commands\n\n");
}
else if (my_strcmp(input[0], "exit") == 0)
{
/*EXIT*/
my_str("Thank you for using MINISHELL\n");
exit(0);
}
else if (input[0] != NULL)
{
/*EXECUTE AN EXTERNAL PROGRAM*/
if ((pid = fork()) < 0)
my_str("MINISHELL: Error forking\n");
else if (pid > 0)
{
wait(NULL);
}
else
{
if (execvp(input[0], input) < 0)
{
my_str("MINISHELL: Error. Program does not exist in current directory.\n");
}
else
{
exit(0);
close(0);
}
}
}
else
{
my_str("MINISHELL: Error reading command. Type help to see available commands.");
}
}
}
return 0;
}
答案 0 :(得分:0)
您不能指望在提示之前始终会打印错误消息。分叉进程与主程序并行运行。从两个程序输出到stdout的顺序取决于OS调度程序如何运行进程。
我认为像bash这样的大多数真正的shell实际上会在执行fork()
之前检查主进程中存在的文件。或者,您可以使用pipe()
并手动重定向输出。然后,您可以在执行提示之前强制刷新整个内容。