ste*_*ang 23 pipe io-redirection arguments
我可以使用任一形式来执行该cat
方法:
cat file_name
cat < file_name
Run Code Online (Sandbox Code Playgroud)
结果是一样的
然后我想以man
格式执行stdin
man < file_name
Run Code Online (Sandbox Code Playgroud)
虽然file_name
包含:
# file_name
cat
Run Code Online (Sandbox Code Playgroud)
但它弹出
What manual page do you want?
而不是 execute man cat
。
我想知道为什么cat
可以接受stdin
作为参数但man
不能。命令行参数和stdin
?之间有什么区别?
use*_*332 23
您的问题与您使用的 shell 如何解析命令行上的用户输入密切相关。
如果在命令行中的第一个字是一个程序,位于一个特殊的文件夹(主要由定义PATH
),并没有更多的特殊字符给出(取决于所使用的shell),所有后续单词分隔用空格或制表符被传递到该程序以特殊形式即数组。将每个单词作为数组中的一个元素。
您将要调用的程序如何解释参数(位于数组中)取决于它的编程方式。关于参数的语法应该是什么样子,有一些准标准,但总的来说,程序员是完全自由的。所以第一个参数可以解释为文件名或程序员在编写程序时的任何想法。
在这种情况下,你的特殊字符添加<
或>
到命令行,外壳不到风度追加<
和>
也没有后续的话,将被传递给程序的阵列。有了<
或>
给定 shell 开始做一些奇特的事情,由底层内核支持(关键字pipe)。要掌握正在发生的事情,您必须了解是什么STDIN
和STDOUT
(因为它不是直接相关的,我省略了STDERR
)。
您在终端上看到的所有可见(在大多数情况下是显示器的一部分)都是由 shell 或您之前调用的任何其他程序写入特殊文件(在unix 中,一切都是文件)。这个文件有一个特殊的 id,叫做STDOUT
. 如果程序想要从键盘读取数据,它不会直接轮询键盘(至少在大多数情况下),而是从名为STDIN
. 在内部,此文件连接到您的标准输入设备,大多数情况下是您的键盘。
如果 shell 读取<
或>
在解析的命令行中,它会在相应的程序运行时操作STDIN
或STDOUT
以特定类型进行操作。STDIN
并且STDOUT
不再指向终端或标准输入设备,而是指向命令行上的后续文件名。
在两条线的情况下
cat file_name
cat < file_name
Run Code Online (Sandbox Code Playgroud)
观察到的行为是相同的,因为相应的开发人员会从文件中cat
读取数据STDIN
或从文件中读取数据,其名称作为第一个命令行参数给出(它是 shell 传递给的数组中的第一个元素cat
)。随后cat
将file_name
或的全部内容写入STDIN
终端,因为我们没有指示外壳操作STDOUT
. 请记住,在第二行中,您的 shellSTDIN
以这种方式操作,它不再指向您的标准输入设备,而是指向file_name
在您当前工作目录中调用的文件。
在该行的其他情况下
man < file_name
Run Code Online (Sandbox Code Playgroud)
man
STDIN
如果不带参数(即空数组)调用它,则不打算从中读取任何内容。所以线
man < file_name
Run Code Online (Sandbox Code Playgroud)
等于
man
Run Code Online (Sandbox Code Playgroud)
例如,如果您传递给,也会man
从 中读取某些内容。使用命令行上给出的此选项,您可以显示从终端读取的任何内容的内容。所以STDIN
-l -
man
man
STDIN
man -l - < file_name
Run Code Online (Sandbox Code Playgroud)
也可以工作(但要注意man
不仅是寻呼机,还要分析文件的输入,因此文件内容和显示的内容可能不同)。
因此,如何STDIN
,STDOUT
以及命令行参数被解释为全部达到相应的开发者。
我希望我的回答可以解决问题。
Mic*_*zek 12
他们完全不同。命令行参数以数组的形式传递给程序,它可以用它们做任何想做的事;stdin 是程序必须从中请求数据的输入流。处理文件的程序通常选择同时支持两者,但它们必须手动执行——它们检查文件名是否作为命令行参数传递,如果不是,则从 stdin 读取
您似乎希望man
阅读 stdin 以找到它应该显示的手册页,这将是一种非常奇怪的行为;你什么时候会用它?这一事实cat
显示其标准输入是,它并没有别的事实的假象; 我认为任何其他工具都不会这样工作。例如,grep
可以采用文件名或从 读取stdin
,但它处理 上的数据stdin
,它不会从中读取文件名stdin
然后打开它
如果您确实需要这种行为,则可以使用xargs
,它将文件转换为命令行参数:
$ xargs man < file_name
Run Code Online (Sandbox Code Playgroud)
或者只是在cat
通话中嵌入man
通话:
$ man $(cat file_name)
Run Code Online (Sandbox Code Playgroud)