stdin / stdout创建的地方

时间:2010-12-16 10:43:11

标签: c stdout stdin

在c(ansi)中,我们说(s / v / f)scanf输入并存储在stdin中,与我们说的相同 stdout。我想知道,在linux(unix)中它们驻留在哪个文件夹下。 或者他们(stdin / stdout)是任意的(也就是说,没有这样的东西存在)

5 个答案:

答案 0 :(得分:4)

它们是操作系统为您的流程创建的流。没有与它们相关联的命名文件对象,因此它们在文件系统中没有表示,尽管解除指出,如果您的UNIX变体支持这样的事情,它们可以通过伪文件系统访问。

答案 1 :(得分:4)

stdinFILE *,指的是与文件描述符0绑定的stdio(标准io)结构。文件描述符是类似Unix的系统,例如Linux,用于与应用程序讨论特定类文件的东西。 (实际上,我很确定Windows也会这样做。)

文件描述符0可以引用任何类型的文件,但有意义的是它必须是read可以被调用的(它必须是常规文件) ,一个蒸汽插座或一个打开用于读取的字符设备或管道的读取端,而不是目录文件,数据克套接字或块设备。

类Unix系统中的进程在类Unix系统中从其父进程继承它们的开放文件描述符。因此,要运行一个程序,将stdin设置为除父级stdin之外的其他东西,你可以这样做:

 int new_stdin = open("new_stdin_file, O_RDONLY);
 pid_t fk = fork();
 if (!fk) { // in the child
     dup2(new_stdin, 0);
     close(new_stdin);
     execl("program_name", "program_name", NULL);
     _exit(127); // should not have gotten here, and calling exit (without _ ) can have
                 // side effects because it runs atexit registered functions, and we
                 // don't want that here
 } else if (fk < 0) {
      // in parent with error from fork
 } else {
     // in parent with no error so fk = pid of child
 }
 close(new_stdin); // we don't need this anymore

dup2将第一个文件描述符参数复制为第二个(如果为当前进程打开,则关闭第二个文件描述符参数)。

fork创建当前进程的副本。 execlexec系列函数之一,它使用execve系统调用将当前程序替换为另一个程序。 forkexec的组合是程序通常运行的方式(即使隐藏在其他函数中)。

在上面的例子中,我们可以运行新程序,将stdin设置为管道的读取端,tty(串行端口/ TeleTYpe)或其他一些东西。其中一些名称存在于文件系统中,而其他名称则不存在(如某些管道和套接字,但有些名称在文件系统中有名称)。

Linux使/proc/self/fd/0成为当前进程中以0打开的文件的符号链接。 /proc/%i/fd/0pid表示使用printf语法对任意pid(进程ID)的同一事物的符号链接。这些符号链接通常可用于在文件系统中查找真实文件(使用readlink系统调用),但如果文件系统中实际不存在该文件,则链接数据(通常是文件名)只是一个字符串这讲了一下这个文件。

我应该在这里指出stdin(fd 0)引用的文件,即使它在文件系统中,也可能没有一个名称。它可能有多个硬链接,因此它有多个名称 - 而且每个名称都与其他任何硬链接一样多。此外,如果它的所有硬链接都已打开unlinked,它可能根本就没有名称,尽管它的数据仍会存在于磁盘上,直到它的所有打开文件描述符都关闭。

如果您实际上不需要知道它在文件系统中的位置,但只是想要一些有关它的数据,您可以使用fstat系统调用。这类似于stat系统调用和命令行实用程序,但已打开的文件除外。

我在这里所说的关于stdin(fd 0)的一切应该适用于stdout(fd 1)和stderr(fd 2),除了它们都是可写的而不是可读的。

如果您想了解我提到的任何功能的更多信息,请务必输入以下内容在手册页中查找:

man fork
命令行上的

。我提到的大多数函数都在手册页的第2部分中,但是一个或两个可能在第一部分中,因此man 2 fork也可以工作,并且当命令行工具与函数同名时可能很有用。

答案 2 :(得分:2)

在Linux中,您通常可以通过stdin中的/proc文件系统找到/proc/self/fd/0,而stdout是/proc/self/fd/1

答案 3 :(得分:1)

stdin是标准输入 - 例如,键盘输入。 stdout是标准输出 - 例如,监视器。

有关详细信息,请阅读this

答案 4 :(得分:0)

如果你跑:

./myprog < /etc/passwd

然后stdin作为/etc/passwd存在于文件系统中。如果你只是运行

./myprog

在终端上以交互方式进行,然后stdin存在于文件系统中,就像您的终端设备一样(可能是/dev/pts/5或其他东西)。

如果你跑

cat /etc/passwd | ./myprog

然后stdin是一个匿名管道,在文件系统中没有实例化,但Linux允许您通过/proc/12345/fd/0获取12345myprog的pid