![输入重定向如何工作?](https://linux22.com/image/891110/%E8%BE%93%E5%85%A5%E9%87%8D%E5%AE%9A%E5%90%91%E5%A6%82%E4%BD%95%E5%B7%A5%E4%BD%9C%EF%BC%9F.png)
是的,我已经尝试在其他地方查找它,但是应该说明输入重定向的示例,例如这里例如,总是有一个令人困惑的警告。在刚刚发布的网站示例中,他们说:
# echo 'hello world' >output
# cat <output
第一行将“hello world”写入文件“output”,第二行将其读回并写入标准输出(通常是终端)。
但是,cat output
会做同样的事情,这里不需要<
。那么有什么区别呢?
答案1
输入重定向(如cat < file
)意味着壳正在打开输入文件并将其内容写入另一个进程的标准输入。将文件作为参数传递(就像运行 时所做的那样cat file
)意味着您正在使用的程序(例如cat
)需要自己打开文件并读取内容。
基本上,command file
通过文件到command
whilecommand < file
经过内容的文件。是的,在像vs 这样的command
情况下,结果没有明显的差异,但是两者的工作方式不同。cat file
cat < file
要理解其中的区别,可以想象一下一个小孩和一个成年人。他们都可以喝水。但是,成年人可以打开水龙头接水(打开文件并阅读其内容),而孩子则需要直接给它喝水(它不能打开文件,只能处理其内容)。
有些程序,例如cat
,能够文件名作为输入,然后打开文件并对其执行操作。这就是cat file
工作原理。然而,其他程序不知道文件是什么或如何使用它们。他们所知道的只是输入流(如文件的内容)。例如tr
:
$ cat file
foo
$ cat file | tr 'o' 'b' ## tr can read a stream
fbb
$ tr 'o' 'b' file ## tr can't deal with files
tr: extra operand ‘file’
Try 'tr --help' for more information.
$ tr 'o' 'b' < file ## input redirection!
fbb
另一个例子是ls
可以很好地处理文件,但忽略输入流:
$ ls
file1 file2
$ ls file1 ## lists only file1: ls takes file names as arguments
file1
$ ls < file1 ## ls ignores its standard input, this is the same as ls alone
file1 file2
其他程序无法处理流,而是需要文件:
$ rm < file ## fails, rm needs a file
rm: missing operand
Try 'rm --help' for more information.
$ rm file ## works, file is deleted
有些程序可以同时处理打开文件和读取输入流,但两者的行为方式不同。例如,wc
当给定一个要打开的文件时,它会打印文件的名称以及行数、单词数和字符数:
$ wc file
1 1 4 file
但是,如果我们只是给它一个流,它就无法知道这是来自一个特定的文件,所以不会打印文件名:
$ wc < file
1 1 4
该md5sum
命令的行为类似:
$ md5sum file
17fd54512c91e3cd0f70fbaaa9a94d0d file
$ md5sum < file
17fd54512c91e3cd0f70fbaaa9a94d0d -
file
请注意,在第一种情况下显示文件名,而在第二种情况下,“文件名”是-
:标准输入。
现在,如果你想要更多细节,你可以使用strace
看看到底发生了什么:
strace -e trace=open,close,read,write wc file 2>strace1.txt
和
strace -e trace=open,close,read,write wc < file 2>strace2.txt
open()
这些将包含进程运行的所有、close()
和操作的所有详细信息read()
。您想要看到的是strace1.txt
(当文件作为参数传递且没有输入重定向时)包含以下行:
open("file", O_RDONLY) = 3
read(3, "foo\n", 16384) = 4
这些意味着文件file
被打开并附加到文件描述符。然后,从读取3
字符串。使用输入重定向时输出的等效部分是:foo\n
3
strace
read(0, "foo\n", 16384) = 4
没有相应的调用,而是从标准输入1读取open()
字符串。foo\n
0
1 默认情况下,0
是标准输入,1
是标准输出,2
是标准错误。顺便说一句,这就是为什么file
打开为3
,那是下一个可用的。
答案2
基本上,区别在于:
cat output.txt
:读取 output.txt 文件的内容到标准输出直接地cat < output.txt
:输出(或内容)输出.txt通过重定向标准输入符号 (<
)由命令读取cat
。因此输出.txt用于<
命令的输入。
两种方法的输出相同,但由于<
重定向标准输入符号,第二种方法采用了额外的路径。