我了解到 Pipe ( |
) 用于将 stdout 传递到子 shell 的 stdin 中。
但是,命令less
必须有文件名参数,例如less file1.txt
但是,当我使用像 之类的命令时ls -l /root | less
,它可以工作。
所以,我假设在这种情况下,需要更少的时间stdin
文件这是从 的ls -l /root
标准输出写入的。我的意思是,实际上,less stdin
当 less 做自己的命令时。但是,由于另一个命令,我感到困惑。这是tr
命令。
tr
命令不接受任何文件论证如tr a-z A-Z file1.txt
.它只是从键盘获取标准输入或重定向的标准输入。但是,命令ls -l /root | tr a-z A-Z
是可能的。那么,我的假设是错误的。
管道在现实中是如何工作的?基本原理是管道将主 shell 的标准输出传递到子 shell 的标准输入。但是,我不知道主 shell 的标准输出会转到子 shell 的标准输入文件或者只是需要我从键盘输入字符的情况。但是,当我看到上面的例子时,shell 会考虑这两种情况。
答案1
我了解到管道 (|) 用于将标准输出传递到子 shell 的标准输入。
它将左侧命令 stdout 传递到右侧命令 stdin。这些命令中的一个或两个是否在子 shell 中运行是特定于 shell 实现的。
无论如何,shell 并不关心是否向任一命令传递参数。程序可以根据自己的需要对标准输入和标准输出进行操作,包括忽略它们。
还要注意的是,程序能够检测它们的标准输入是否是tty
交互式键盘,并采取相应的行动。这是您在less
命令中观察到的情况,当没有给出参数时,通常读取其标准输入,但如果它是 a 则拒绝处理它tty
,因为它的源代码显示:
if (isatty(fd0))
{
error("Missing filename (\"less --help\" for help)", NULL_PARG);
quit(QUIT_OK);
}
答案2
所以,我假设在这种情况下,
less
需要stdin
文件这是从 的ls -l /root
标准输出写入的。
这是正确的,并且与您观察到的内容并不矛盾tr
。
外壳的管道构造 ( ) 创建一个PRODUCER | CONSUMER
匿名管道在启动两个进程PRODUCER
和之前CONSUMER
。匿名管道是一种没有名称、没有目录项、但可以正常读写的文件类型。在管道中,shell 将管道的写入端连接到生产者的标准输出,将管道的读取端连接到消费者的标准输入。
该tr
命令仅从 stdin 读取数据并写入 stdout。less
仅当您不在命令行上向其传递文件名时,该命令才会执行此操作;如果将文件名传递给less
,它将从此文件中读取而不是从标准输入中读取。所做less
的是一种通用约定,随后是许多从一个文件读取数据的类似应用程序。
您也可能对。。。有兴趣连接 STDOUT 和 STDIN 是什么意思?和一个命令如何可以有多个输出?