11

给定一个文件"foo.txt",创建自:

$ seq 1 10 > "foo.txt"

我正在尝试读取文件的第一行和最后一行,我首先将文件重定向到子shell,以便命令列表将按顺序使用文件——每个命令都使用从点的输入最后一个命令已经离开它,我想

$ (head -1; tail -1) < "foo.txt"
1
10

但是,如果我尝试使用临时文件描述符进行相同操作,则输出不一样:

$ (head -1; tail -1) < <(seq 1 10)
1

问题

  1. 我不确定要命名什么<(seq 1 10),但这个临时文件描述符和常规文件描述符( "foo.txt") 有什么区别,导致子 shell 执行行为不同?

  2. 我怎样才能实现将 a 重定向"foo.txt"到子 shell 的相同行为,但没有临时文件——而不实际创建文件。

4

1 回答 1

11

这只是一个缓冲问题。尝试:

cat foo.txt | ( head -1; tail -1)

你会(可能)看到同样的事情(head 消耗了整个输入)。可能正在发生的事情是 head 对常规文件的行为与使用管道不同,并且进程替换(这是<(cmd)语法的名称)正在创建管道。(在 Linux 中,head来自 Gnu coreutils 的lseek尝试在它输出的最后一个换行符处重新定位,但在lseek管道上失败了。)

也试试:

(head -1; tail -1) < <(cat /usr/share/dict/words)

这里,head只消耗输入的第一页,tail 看到数据的最后一行。

您看到的行为没有明确定义,因为没有标准规定允许使用多少数据头。如果您替换headsh -c 'read line; echo "$line"',那么您将在所有情况下都获得所需的行为。(或者编写你自己的工具来提供head你想要的行为——打印固定数量的行而不消耗更多。)

于 2013-09-24T13:33:22.867 回答