在c(ansi)中,我们说(s / v / f)scanf输入并存储在stdin中,与我们说的相同 stdout。我想知道,在linux(unix)中它们驻留在哪个文件夹下。 或者他们(stdin / stdout)是任意的(也就是说,没有这样的东西存在)
答案 0 :(得分:4)
它们是操作系统为您的流程创建的流。没有与它们相关联的命名文件对象,因此它们在文件系统中没有表示,尽管解除指出,如果您的UNIX变体支持这样的事情,它们可以通过伪文件系统访问。
答案 1 :(得分:4)
stdin
是FILE *
,指的是与文件描述符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
创建当前进程的副本。 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)引用的文件,即使它在文件系统中,也可能没有一个名称。它可能有多个硬链接,因此它有多个名称 - 而且每个名称都与其他任何硬链接一样多。此外,如果它的所有硬链接都已打开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
获取12345
是myprog
的pid