标准流 stdin 和 stdout 在哪里创建?
在 ANSI C 中,我们说输入由 (s/v/f)scanf 获取并存储在 stdin
中,在谈论输出时我们说 stdout
。不过我想知道它们在 Linux (Unix) 中的位置。它们驻留在特定文件夹下吗?或者它们(stdin
/stdout
)是任意的(也就是说,不存在这样的东西)?
In ANSI C, we say input is taken by (s/v/f)scanf and stored in stdin
, we say something for stdout
when talking about output. However I wonder where they reside in Linux (Unix). Do they reside under a specific folder? Or are they (stdin
/stdout
) arbitrary (that is, no such things exist)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
它们是操作系统为您的进程创建的流。没有与它们关联的命名文件对象,因此它们在文件系统中没有表示,尽管正如 unwind 指出的那样,如果您的 UNIX 变体支持这样的东西,则可以通过伪文件系统访问它们。
They are streams created for your process by the operating system. There is no named file object associated with them, and so they do not have a representation within the file system, although as unwind points out, they may be accessed via a pseudo file system if your UNIX variant supports such a thing.
stdin
是一个FILE *
,引用与文件描述符0
绑定的 stdio(标准 io)结构。文件描述符是类 Unix 系统(例如 Linux)用来与应用程序讨论特定的类似文件的事物的东西。 (实际上,我很确定 Windows 也能做到这一点)。文件描述符
0
可以引用任何类型的文件,但为了有意义,它必须是可以调用read
的文件描述符(它必须是常规文件、steam 套接字或打开用于读取的字符设备或管道的读取端,而不是目录文件、数据报套接字或块设备)。类 Unix 系统中的进程从类 Unix 系统中的父进程继承其打开的文件描述符。因此,要运行一个将标准输入设置为父级标准输入之外的内容的程序,您可以执行以下操作:
dup2
将第一个文件描述符参数复制为第二个文件描述符参数(如果它为当前进程打开,则在执行此操作之前关闭第二个文件描述符参数) )。fork
创建当前进程的副本。execl
是exec
系列函数之一,它使用execve
系统调用将当前程序替换为另一个程序。fork
和exec
的组合是程序通常的运行方式(即使隐藏在其他函数中)。在上面的示例中,我们可以运行新程序,并将 stdin 设置为管道、tty(串行端口/TeleTYpe)或其他几个东西的读取端。其中一些在文件系统中具有名称,而另一些则没有(例如某些管道和套接字,尽管有些在文件系统中确实有名称)。
Linux 使
/proc/self/fd/0
成为当前进程中以0
打开的文件的符号链接。/proc/%i/fd/0
,pid
将使用printf
表示任意 pid(进程 ID)到同一事物的符号链接代码>语法。这些符号链接通常可用于在文件系统中查找真实文件(使用 readlink 系统调用),但如果文件实际上不存在于文件系统中,则链接数据(通常是文件名)只是一个字符串这告诉了一些关于该文件的信息。我应该在这里指出,stdin (fd 0) 引用的文件,即使它位于文件系统中,也可能不只有一个名称。它可能有多个硬链接,因此它也有多个名称——每一个名称都与任何其他硬链接一样多。此外,如果自打开以来它的所有硬链接都已
取消链接
,则它可能根本没有名称,尽管它的数据仍然存在于磁盘上,直到它的所有打开的文件描述符都被关闭。如果您实际上不需要知道它在文件系统中的位置,而只是想要一些有关它的数据,您可以使用
fstat
系统调用。这类似于 stat 系统调用和命令行实用程序,但已打开的文件除外。我在这里所说的关于 stdin (fd 0) 的所有内容都应该适用于 stdout (fd 1) 和 stderr (fd 2),只不过它们都是可写的而不是可读的。
键入:在手册页中查找它们
如果您想了解有关我提到的任何函数的更多信息,请务必通过在命令行上 。我提到的大多数函数都在手册页的第 2 部分中,但一两个可能在第 1 部分中,因此
man 2 fork
也可以工作,并且当命令行工具具有相同的功能时可能会很有用名称作为函数。stdin
is aFILE *
referring to the stdio (standard io) structure that is tied to the file descriptor0
. File descriptors are what Unix-like systems, such as Linux, use to talk with applications about particular file-like things. (Actually, I'm pretty sure that Windows does this as well).File descriptor
0
may refer to any type of file, but to make sense it must be one thatread
can be called on (it must be a regular file, a steam socket, or a character device opened for reading or the read side of a pipe, as opposed to a directory file, data gram socket, or a block device).Processes in Unix-like systems inherit their open file descriptors from their parent process in Unix-like systems. So to run a program with stdin set to something besides the parent's stdin you would do:
dup2
duplicates the first file descriptor argument as the second (closing the second before doing so if it were open for the current process).fork
creates a duplicate of the current process.execl
is one of theexec
family of functions, which use theexecve
system call to replace the current program with another program. The combination offork
andexec
are how programs are generally run (even when hidden within other functions).In the above example we could have run the new program with stdin set to the read end of a pipe, a tty (serial port / TeleTYpe), or several other things. Some of these have names present in the filesystem and others do not (like some pipes and sockets, though some do have names in the filesystem).
Linux makes
/proc/self/fd/0
a symbolic link to the file opened as0
in the current process./proc/%i/fd/0
,pid
would represent the symbolic link to the same thing for an arbitrary pid (process ID) using theprintf
syntax. These symbolic links are often usable to find the real file in the filesystem (using the readlink system call), but if the file does not actually exist in the filesystem the link data (what would usually be a file name) instead is just a string that tells a little bit about the file.I should point out here that a file that stdin (fd 0) refers to, even if it is in the filesystem, may not have just one name. It may have more than one hard link, so it would have more than one name -- and each of these would be just as much its name as any other hard link. Additionally it may have no name at all if all of its hard links have been
unlinked
since it was opened, though it's data would still live on the disk until all open file descriptors for it are closed.If you don't actually need to know where it is in the filesystem, but just want some data about it you can use the
fstat
system call. This is like thestat
system call and command line utility, except for already open files.Everything I said here about
stdin
(fd 0) should be applicable to stdout (fd 1) and stderr (fd 2) except that they will both be writable rather than readable.If you want to know more about any of the functions I mentioned be sure to look them up in the man pages by typing:
on the command line. Most functions I mentioned are in section 2 of the man pages, but one or two may be in section one, so
man 2 fork
will work too, and may be useful when a command line tool has the same name as a function.在 Linux 中,您通常可以通过 /proc 文件系统找到
stdin
在/proc/self/fd/0
中,标准输出为/proc/self/fd/1
。In Linux, you can generally find
stdin
through the /proc file system in/proc/self/fd/0
, and stdout is/proc/self/fd/1
.stdin
是标准输入 - 例如键盘输入。stdout
是标准输出 - 例如,监视器。如需了解更多信息,请阅读此。
stdin
is standard input - for example, keyboard input.stdout
is standard output - for example, monitor.For more info, read this.
如果运行:
则
stdin
在文件系统中以/etc/passwd
形式存在。如果您只是在终端上交互运行,那么
stdin
就存在于文件系统中,无论您的终端设备是什么(可能是/dev/pts/5
或其他设备)。如果您运行,
则
stdin
是一个匿名管道,并且在文件系统中没有实例化,但 Linux 允许您通过/proc/12345/fd/0
获取它,其中 < code>12345 是myprog
的 pid。If you run:
then
stdin
exists in the filesystem as/etc/passwd
. If you just runinteractively on a terminal, then
stdin
exists in the filesystem as whatever your terminal device is (probably/dev/pts/5
or something).If you run
then
stdin
is an anonymous pipe and has no instantiation in the filesystem, but Linux allows you to get at it via/proc/12345/fd/0
where12345
is the pid ofmyprog
.