C语言 写入标准输入和读取标准输出(UNIX/LINUX/C 编程)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7383803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Writing to stdin and reading from stdout (UNIX/LINUX/C Programming)
提问by Tim
I was working on an assignment where a program took a file descriptor as an argument (generally from the parent in an exec call) and read from a file and wrote to a file descriptor, and in my testing, I realized that the program would work from the command-line and not give an error if I used 0, 1 or 2 as the file descriptor. That made sense to me except that I could write to stdin and have it show on the screen.
我正在做一项作业,其中程序将文件描述符作为参数(通常来自 exec 调用中的父级)并从文件中读取并写入文件描述符,在我的测试中,我意识到该程序可以工作如果我使用 0、1 或 2 作为文件描述符,则不会出现错误。这对我来说很有意义,只是我可以写入 stdin 并将其显示在屏幕上。
Is there an explanation for this? I always thought there was some protection on stdin/stdout and you certainly can't fprintf to stdin or fgets from stdout.
对此有解释吗?我一直认为对标准输入/标准输出有一些保护,你当然不能从标准输出到标准输入或 fgets 的 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;
}
回答by Dave
Attempting to write on a file marked readonly or vice-versa would cause writeand readto return -1, and fail. In this specificcase, stdin and stdout are actually the same file. In essence, before your program executes (if you don't do any redirection) the shell goes:
尝试写入标记为只读或反之亦然的文件将导致write并read返回 -1,并失败。在这种特定情况下,stdin 和 stdout 实际上是同一个文件。本质上,在您的程序执行之前(如果您不进行任何重定向),shell 会执行以下操作:
if(!fork()){
<close all fd's>
int fd = open("/dev/tty1", O_RDWR);
dup(fd);
dup(fd);
execvp("name", argv);
}
So, stdin, out, and err are all duplicates of the same file descriptor, opened for reading and writing.
因此,stdin、out 和 err 都是同一个文件描述符的副本,打开用于读取和写入。
回答by Ed Heal
read(STDIN_FILENO, message, 20);
write(STDOUT_FILENO, message, 20);
Should work. Note - stdout my be a different place from stdin (even on the command line). You can feed output from another process as stdin into you process, or arrange the stdin/stdout to be files.
应该管用。注意 - 标准输出与标准输入不同(即使在命令行上)。您可以将另一个进程的输出作为标准输入输入到您的进程中,或者将标准输入/标准输出安排为文件。
fprintf/fgets have a buffer - thus reducing the number of system calls.
fprintf/fgets 有一个缓冲区 - 从而减少系统调用的数量。
回答by Peter Lawrey
If you run a program on UNIX
如果您在 UNIX 上运行程序
myapp < input > output
You can open /proc/{pid}/fd/1 and read from it, open /proc/{pid}/fd/0 and write to it and for example, copy outputto input. (There is possibly a simpler way to do this, but I know it works)
您可以打开 /proc/{pid}/fd/1 并从中读取,打开 /proc/{pid}/fd/0 并写入它,例如,复制output到input. (可能有一种更简单的方法可以做到这一点,但我知道它有效)
You can do any manner of things which are plain confusing if you put your mind to it. ;)
如果你全神贯注,你可以做任何令人困惑的事情。;)
回答by Avery3R
Best guess - stdin points to where the input is coming from, your terminal and stdout points to where output should be going, your terminal. Since they both point to the same place they are interchangeable(in this case)?
最佳猜测 - stdin 指向输入来自哪里,您的终端和 stdout 指向输出应该去哪里,您的终端。因为它们都指向同一个地方,所以它们可以互换(在这种情况下)?
回答by R.. GitHub STOP HELPING ICE
It's very possible that file descriptors 0, 1, and 2 are all open for both reading and writing (and in fact that they all refer to the same underlying "open file description"), in which case what you're doing will work. But as far as I know, there's no guarantee, so it also might not work. I do believe POSIX somewhere specifies that if stderr is connected to the terminal when a program is invoked by the shell, it's supposed to be readable and writable, but I can't find the reference right off..
很可能文件描述符 0、1 和 2 都为读取和写入打开(实际上它们都引用相同的底层“打开文件描述”),在这种情况下,您正在执行的操作将起作用。但据我所知,不能保证,所以它也可能不起作用。我确实相信 POSIX 某处指定如果在 shell 调用程序时将 stderr 连接到终端,它应该是可读和可写的,但我无法立即找到参考..
Generally, I would recommend against ever reading from stdout or stderr unless you're looking for a terminal to read a password from, and stdin has been redirected (not a tty). And I would recommend never writing to stdin - it's dangerous and you could end up clobbering a file the user did not expect to be written to!
通常,我建议不要从 stdout 或 stderr 读取,除非您正在寻找一个终端来读取密码,并且 stdin 已被重定向(不是 tty)。而且我建议永远不要写入标准输入 - 这很危险,您最终可能会破坏用户不希望写入的文件!
回答by vinllen
If you want to write message into stdin, you can open current tty, and call writesystem call to write message into this fd:
如果要将消息写入标准输入,可以打开当前的 tty,并调用write系统调用将消息写入该 fd:
string console_cmd = "hello";
string tty = ttyname(STDIN_FILENO);
int fd = open(tty.c_str(), O_WRONLY);
write(fd, console_cmd.c_str(), console_cmd.size());
Similarly, read from stdout.
同样,从标准输出读取。

