为什么有些命令不采用输入重定向?

为什么有些命令不采用输入重定向?

例如,回声

[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

将从 读取,然后从标准输入读取,然后从 读取。但是,如果命令通常不读取在命令行上指定名称的文件的内容,那么它可能也不会对标准输入执行任何操作。  从不从文件读取。file1file2echo

当然,也有各种例外:

  • tr命令始终从标准输入读取,并且不接受命令行上的文件名。
  • 如果bc使用文件名参数调用,它会读取它们, 然后还有读取标准输入,除非其中一个文件具有haltquit命令。
  • 编译器(例如,C 编译器,可以称为ccgcc)倾向于要求(或至少强烈倾向于)在命令行上使用文件名。  cc如果在命令行上没有文件名的情况下调用将会失败。  cc -仅当指定了某些选项时才会读取标准输入。
  • 使用少于两个输入源来调用cmp或 是没有意义的。如果在命令行上没有文件名的情况下调用它们,它们将失败。它们都遵守 的参数指定标准输入的约定。  相当于;即,它将与标准输入  进行比较。如果使用一个文件名参数调用,则会失败;您需要说。diff-cmp file1cmp file1 -file1diffdiff file1 -
  • 并且,虽然dd会接受输入F如果命令行中指定了 ile,则表示为,例如,if=filename

    dd if=my_iso_file of=/dev/sda1
    

    ofo输出File),如果你不指定任何内容,它将从标准输入读取if;例如,

    dd of=/dev/sda1 < my_iso_file
    

    它不接受命令行参数未加修饰的文件名 ( 例如dd my_iso_file > /dev/sda1dd my_iso_file of=/dev/sda1不是工作)。 (此外,与大多数从文件读取的命令不同, dd它不会处理来自命令行的多个输入文件。)

(可能还有其他。)

答案3

阅读文档。

echo 命令不从 stdin 读取。因此,输入重定向不执行任何操作。Bash 手册指出:

echo:输出参数,以空格分隔,后跟换行符。

手册页cat

cat—连接文件并在标准输出上打印。

相关内容