对于某些命令,可以将某些输入指定为 stdin 或命令行参数。
具体来说,假设command
可以将 stdin 输入和文件名作为命令行参数,并且command < myfile
、cat myfile | command
和command myfile
可以产生相同的结果。
例如,
当命令是sed
:
sed s/day/night/ <myfile >new
sed s/day/night/ myfile >new
cat myfile | sed s/day/night/ >new
当命令是cat
:
cat < myfile
cat myfile
- 我想知道他们的表现是否有一些通用规则,即哪一个通常是最有效率的,哪一个是最没有效率的?
- 重定向总是比管道更好吗?
答案1
该cat file | command
语法被认为是无用的使用Cat
。在所有选项中,它会影响性能,因为它必须在内核中生成另一个进程。无论这在大局中可能显得微不足道,但它的开销是其他形式所没有的。这已经涉及到以下问题:我应该关心不必要的猫吗?
其他两种形式之间几乎没有性能差异。 STDIN 是一个特殊的文件节点,进程必须像其他文件一样打开和读取它。传递文件名而不是 STDIN 只会使其打开不同的文件。
区别在于您正在寻找什么功能/灵活性。
- 将文件名传递给程序意味着输入文件是可查找的。这对程序可能重要也可能无关紧要,但如果流是可查找的,则某些操作可以加快。
- 了解实际的输入文件使您的程序有可能对其进行写入。例如
sed -i
用于就地编辑。 (注意:由于这必须在幕后创建一个新文件,因此与其他重定向相比并没有性能提升,但这是一个方便的步骤。) - 使用 shell 重定向使您能够连接多个文件,甚至使用进程重定向。
sed [exp] < file1 file2
甚至sed [exp] < <(grep command)
。此用例的详细信息可以在这个问题上找到:进程替换和管道
答案2
鉴于
command file
只需打开文件,从那时起就可以像以前一样工作stdin
,几乎没有什么区别。使用 shell 重定向,您只需预先打开文件(shell 会这样做),而不是命令二进制文件本身。如果我们谈论
cat file | command
vs.command <file
,那么后者是首选。您不会注意到两者之间显着的性能差异,但前者不必要地复杂(管道的额外进程和共享内存缓冲区,吞吐量有限。)此外,您不能seek
(任意更改文件指针位置)管道,而您可以在普通文件中。当seek
输入文件中可以使用 -ing时,某些命令可能会使用更有效的算法。