例如,回声:
[aesteban@localhost ~]$ cat tmp.txt
Angel
[aesteban@localhost ~]$ echo < tmp.txt
[aesteban@localhost ~]$
如您所见,输出只是一个空行。根据我的阅读,一些命令能够进行输入重定向,例如邮件:
[aesteban@localhost ~]$ mail [email protected] < tmp.txt
那么输入重定向是否仅适用于交互式命令(能够等待输入的命令)?如何确定命令是否是交互式的(除了尝试之外)?
答案1
为什么有些命令不采用输入重定向?
简短的回答是:因为他们没有被编程这样做。
对于程序来说,读取stdin
(即 shell 连接到 之后指定的文件的流<
)不是自动的。它需要由程序员编写代码。就此而言,从命令行给出的文件读取也不是自动的。也就是说,这些文件的内容(无论是通过重定向给出还是通过名称指定)不会在没有额外编码的情况下神奇地出现在程序的变量中。
如果程序从未被编码为从流中读取,那么无论你是否设置重定向都无关紧要 - 它都不会从中读取。根据其 POSIX 规范(http://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html)echo
不需要从 读取stdin
,并且只检查其命令行参数(和一些环境变量)。要了解其他程序,您可以阅读源代码、文档,或者简单地按照您所说的尝试一下 :-)
回答你的最后一个问题:你不能真正地说一个命令是交互式的。能确定它正在读取的输入流是否连接到终端(而不是例如纯文件)。在http://rosettacode.org/wiki/Check_input_device_is_a_terminal。您可以设想一个邮件程序,使用此功能来确定它是以交互方式使用(接受键盘命令来读取邮件),还是以非交互方式使用(例如,从文件中读取邮件消息)。我不确定它是如何mail
做到的。(请注意,mail
使用或不使用命令行参数调用时的行为会有所不同!)
答案2
大多数读取在命令行中指定了名称的文件(或多个文件)内容的命令,如果在命令行中未指定文件,则会从标准输入读取。如果在命令行中指定了文件名,某些命令也会从标准输入读取-
;例如,
猫文件1 - 文件2
将从 读取,然后从标准输入读取,然后从 读取。但是,如果命令通常不读取在命令行上指定名称的文件的内容,那么它可能也不会对标准输入执行任何操作。 从不从文件读取。file1
file2
echo
当然,也有各种例外:
- 该
tr
命令始终从标准输入读取,并且不接受命令行上的文件名。 - 如果
bc
使用文件名参数调用,它会读取它们, 然后还有读取标准输入,除非其中一个文件具有halt
或quit
命令。 - 编译器(例如,C 编译器,可以称为
cc
或gcc
)倾向于要求(或至少强烈倾向于)在命令行上使用文件名。cc
如果在命令行上没有文件名的情况下调用将会失败。cc -
仅当指定了某些选项时才会读取标准输入。 -
使用少于两个输入源来调用
cmp
或 是没有意义的。如果在命令行上没有文件名的情况下调用它们,它们将失败。它们都遵守 的参数指定标准输入的约定。 相当于;即,它将与标准输入 进行比较。如果使用一个文件名参数调用,则会失败;您需要说。diff
-
cmp file1
cmp file1 -
file1
diff
diff file1 -
并且,虽然
dd
会接受我输入F如果命令行中指定了 ile,则表示为,例如,if=filename
dd if=my_iso_file of=/dev/sda1
(
of
是o输出File),如果你不指定任何内容,它将从标准输入读取if
;例如,dd of=/dev/sda1 < my_iso_file
它不接受命令行参数是未加修饰的文件名 ( 例如
dd my_iso_file > /dev/sda1
,dd my_iso_file of=/dev/sda1
不是工作)。 (此外,与大多数从文件读取的命令不同,dd
它不会处理来自命令行的多个输入文件。)
(可能还有其他。)
答案3
阅读文档。
echo 命令不从 stdin 读取。因此,输入重定向不执行任何操作。Bash 手册指出:
echo:输出参数,以空格分隔,后跟换行符。
手册页cat
:
cat—连接文件并在标准输出上打印。