写入stdin并从stdout读取(UNIX / LINUX / C编程)

时间:2011-09-12 05:54:40

标签: c unix stdout stdin read-write

我正在进行一项任务,程序将文件描述符作为参数(通常来自exec调用中的父项)并从文件中读取并写入文件描述符,在我的测试中,我意识到程序将从命令行工作,如果我使用0,1或2作为文件描述符,则不会出错。这对我来说很有意义,除了我可以写入stdin并让它显示在屏幕上。

对此有解释吗?我一直认为在stdin / stdout上有一些保护,你当然不能从stdout到stdin或fgetsf fprintf。

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    char message[20];
    read(STDOUT_FILENO, message, 20);
    write(STDIN_FILENO, message, 20);

    return 0;
}

5 个答案:

答案 0 :(得分:11)

尝试在标记为readonly或反之亦然的文件上写入会导致writeread返回-1,并失败。在这个特定的情况下,stdin和stdout实际上是同一个文件。实质上,在程序执行之前(如果你不进行任何重定向),shell会:

  if(!fork()){
       <close all fd's>
       int fd = open("/dev/tty1", O_RDWR);
       dup(fd);
       dup(fd);
       execvp("name", argv);
  }

因此,stdin,out和err都是同一个文件描述符的副本,为读写而打开。

答案 1 :(得分:2)

read(STDIN_FILENO, message, 20); 
write(STDOUT_FILENO, message, 20);

应该有效。注意 - stdout我与stdin不同(甚至在命令行上)。您可以将另一个进程的输出作为stdin提供给您进程,或者将stdin / stdout安排为文件。

fprintf / fgets有一个缓冲区 - 从而减少了系统调用次数。

答案 2 :(得分:1)

最佳猜测 - stdin指向输入的来源,终端和stdout指向输出应该到达的位置,终端。既然它们都指向同一个地方它们是可以互换的(在这种情况下)?

答案 3 :(得分:1)

如果您在UNIX上运行程序

myapp < input > output

你可以打开/ proc / {pid} / fd / 1并从中读取,打开/ proc / {pid} / fd / 0并写入它,例如,将output复制到{{1 }}。 (可能有一种更简单的方法,但我知道它有效)

如果你坚持下去,你可以做任何容易混淆的事情。 ;)

答案 4 :(得分:0)

文件描述符0,1和2很可能都是开放的,用于读取和写入(实际上它们都引用相同的底层“打开文件描述”),在这种情况下你正在做什么将工作。但据我所知,没有保证,所以它也可能不起作用。我确实认为POSIX某处指定如果stderr在shell调用程序时连接到终端,它应该是可读写的,但是我找不到引用权。

一般来说,我建议不要读取stdout或stderr,除非你正在寻找一个终端来读取密码,并且stdin已被重定向(不是tty)。我建议永远不要写入stdin - 这很危险,你最终可能会破坏用户不希望写入的文件!