【发布时间】:2016-03-20 12:33:00
【问题描述】:
我正在尝试在 Linux 上编写一个可以执行单进程命令、双进程管道和 I/O 重定向的 shell 模拟器。 但是,当我使用以下正确执行单个进程时,管道存在一些问题。
Copy_STDIO(); //Copy the stdio for the restoration.
Redirection(); //Determine whether should do Redirection.
Pipeline();
Restore_stdio(); //Restore the stdio.
以上是我在 main 中的函数。首先,我复制 STDIO 以在 I/O 重定向后进行恢复。然后我将我的文件描述符复制到 STD_IN 和 STD_OUT。然后我执行 Pipeline,最后我恢复了我的 STD_IN 和 STD_OUT。一切听起来都很完美,但实际上并非如此。我的 OUTPUT 重定向失败,这意味着当我的程序仍在运行时,它没有向目标文件写入任何内容(即,如果在单一情况下:ls > 123, 123 不显示任何内容)。但是当我用exit(EXIT_SUCCESS)终止程序时,它出现了!!(如果用ctrl+c,它也失败了),我不知道为什么!
void Redirection()
{
fd_out = open(filename[0],O_WRONLY | O_TRUNC | O_CREAT,S_IRWXU | S_IRWXG | S_IRWXO); //O_WRONLY and O_CREAT must use at the same time.
dup2(fd_out,STD_OUTPUT);
close(fd_out);
}
void Copy_STDIO()
{
STDIN_COPY = dup(STD_INPUT); //Copy for the stdin and stdout
STDOUT_COPY = dup(STD_OUTPUT);
}
void Pipeline()
{
if(pipeline)
{
pipe(&fd[0]);
childID=fork();
if(childID==0)
{
if(fork()!=0)
{
close(fd[1]);
dup2(fd[0],STD_INPUT);
close(fd[0]);
execvp(args2[0],args2);
}
else
{
close(fd[0]);
dup2(fd[1],STD_OUTPUT);
close(fd[1]);
execvp(args[0],args);
}
}
usleep(5000);
}
}
void Restore_stdio()
{
dup2(STDIN_COPY,STD_INPUT); //Restore the output and input to the stdin and stdout.
dup2(STDOUT_COPY,STD_OUTPUT);
close(STDIN_COPY);
close(STDOUT_COPY);
}
【问题讨论】:
-
你能提供一个最小可验证的例子,也就是一段可以编译的代码吗?
-
文件需要关闭才能被查看和阅读。退出(0);关闭所有打开的文件。
-
@ArifBurhan 我应该在哪里添加 exit(0); ?我将 fd_out 重定向到 STD_OUTPUT 后关闭了它。
-
@RobertLee 使用
ls 123 > 123对我来说效果很好。 -
@PatrickTrentin 是的,但我的管道会出错。试试猫 123 | grep a > 456。然后输入 cat 456。如果正确,它将显示文件的内容。我的意思是,文件 456 只会在程序终止时显示内容,但不会在程序期间显示。
标签: c linux shell redirect pipeline