打开文件和打开 STDIN 之间的区别,何时使用每个文件

打开文件和打开 STDIN 之间的区别,何时使用每个文件

在很多答案中,主要是关于text-processing命令,我看到诸如sedawkgrep等命令与 STDIN 一起使用以及简单地打开文件

例如

$ sed -e 's|foo|bar|g' file # open file
$ sed -e 's|foo|bar|g' <file # open STDIN

或者

$ grep 'PATTERN' file # open file
$ grep 'PATTERN' <file # open STDIN

就个人而言,我总是使用打开文件方法,但我想知道何时和何时不使用它们,以及有什么区别。

答案1

这取决于需要。在这种情况下,使用文件名或来自标准输入的管道会产生影响。

bash-4.1$ cat /etc/passwd /etc/group | wc -l
128
bash-4.1$ wc -l /etc/passwd /etc/group
  49 /etc/passwd
  79 /etc/group
 128 total
bash-4.1$ 

此外,标准输入往往不是很lseek(3)强大,因此如果应用程序需要一个可以查找的文件描述符(例如倒回到开头),则可能会排除使用标准输入的可能性。

答案2

就输出而言,没有什么区别。

$ grep 'PATTERN' file将打开参数 2 中指定的文件并搜索模式。

$ grep 'PATTERN' <filefile将读取into的内容STDIN(bash 的功能之一),并将通过管道传输STDINgrep.

我不确定其中之一是否有确切的好处,但我会继续使用前者而不是后者。

后者是多余的,就像cat file | grep 'PATTERN'cat file | sed -e 's|foo|bar|g'是多余的一样。

答案3

在某些情况下,两者并不完全相同,例如:

$ wc -l ./script.sh
4948 ./script.sh
$ wc -l <./so
4948

首先wc知道正在处理哪个文件并打印文件名和行数。在第二个中,该命令wc不知道正在处理什么文件,它是匿名输入。

在使用 grep 的示例的特定命令中:

$ grep 'PATTERN' file
$ grep 'PATTERN' <file

输出没有区别。但有了这个,就有了(如果有匹配的话):

$ grep -H 'PATTERN' file
$ grep -H 'PATTERN' <file

此外,在重定向的情况下<file,shell 正在读取文件,这也可能对缓冲的速度或大小(对于不同的命令)产生影响。

答案4

区别主要在于谁打开文件。这可能很重要安全原因-- shell 可能具有启动的程序所没有的特权。

使用 STDIN 方法意味着将流继承到由启动的程序创建的整个进程树。这在某些情况下可能很有用。

随着打开文件方法,启动的程序更容易知道文件名。采用文件名路由的程序可能会在其输出中使用文件名,并且文件名路由可能在其他方面有所不同,例如性能:程序通常假设仅对 STDIN 进行基本流访问(无查找,无映射性)以及文件名参数的可查找性。

相关内容