是的,我已经尝试在其他地方查找它,但是应该说明输入重定向的示例,例如这里,总是有一个令人困惑的警告。在刚刚发布的网站示例中,他们说:
# echo 'hello world' >output
# cat <output
Run Code Online (Sandbox Code Playgroud)
第一行将“hello world”写入文件“output”,第二行将其读回并将其写入标准输出(通常是终端)。
但是,cat output
会做完全相同的事情,<
这里没有。那么区别是什么呢??
输入重定向(如cat < file
)意味着shell正在打开输入文件并将其内容写入另一个进程的标准输入。将文件作为参数传递(正如您在运行时所做的那样cat file
)意味着您正在使用的程序(例如cat
)需要打开文件本身并读取内容。
基本上,command file
将文件传递给command
而command < file
将文件的内容传递给command
. 是的,在像cat file
vscat < 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
Run Code Online (Sandbox Code Playgroud)
另一个例子是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
Run Code Online (Sandbox Code Playgroud)
其他程序无法处理流,而是需要文件:
$ rm < file ## fails, rm needs a file
rm: missing operand
Try 'rm --help' for more information.
$ rm file ## works, file is deleted
Run Code Online (Sandbox Code Playgroud)
一些程序可以处理打开文件和读取输入流,但它们的行为方式不同。例如,wc
当给定要打开的文件时,它会打印文件名以及行数、单词数和字符数:
$ wc file
1 1 4 file
Run Code Online (Sandbox Code Playgroud)
但是,如果我们只是给它一个流,它无法知道这是来自特定文件,因此不会打印文件名:
$ wc < file
1 1 4
Run Code Online (Sandbox Code Playgroud)
该md5sum
命令的行为类似:
$ md5sum file
17fd54512c91e3cd0f70fbaaa9a94d0d file
$ md5sum < file
17fd54512c91e3cd0f70fbaaa9a94d0d -
Run Code Online (Sandbox Code Playgroud)
请注意,在第一种情况下显示文件名file
,而在第二种情况下,“文件名”是-
:标准输入。
现在,如果您想了解更多详细信息,您可以使用它strace
来查看到底发生了什么:
strace -e trace=open,close,read,write wc file 2>strace1.txt
Run Code Online (Sandbox Code Playgroud)
和
strace -e trace=open,close,read,write wc < file 2>strace2.txt
Run Code Online (Sandbox Code Playgroud)
那些将所有的所有细节open()
,close()
并read()
操作由进程中运行。您想看到的是strace1.txt
(当文件作为参数传递而不是输入重定向时)包含以下几行:
open("file", O_RDONLY) = 3
read(3, "foo\n", 16384) = 4
Run Code Online (Sandbox Code Playgroud)
这些意味着文件file
被打开并附加到文件描述符3
。然后,从foo\n
中读取字符串3
。strace
使用输入重定向时输出的等效部分是:
read(0, "foo\n", 16384) = 4
Run Code Online (Sandbox Code Playgroud)
没有相应的open()
调用,而是foo\n
从0
标准输入1读取字符串。
1 默认情况下,0
是标准输入、1
标准输出和2
标准错误。顺便说一下,这就是为什么file
打开为3
,那是下一个可用的。
归档时间: |
|
查看次数: |
10504 次 |
最近记录: |