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

$ seq 1 10 > "foo.txt"

我正在尝试读取文件的第一行和最后一行,我首先将文件重定向到子shell,以便命令列表按顺序使用该文件——每个命令都使用从点开始的输入最后一个命令已经离开它, 我想 :
$ (head -1; tail -1) < "foo.txt"
1
10

但是,如果我对临时文件描述符尝试相同的操作,则输出不一样:
$ (head -1; tail -1) < <(seq 1 10)
1

问题 :
  • 我不确定要命名什么 <(seq 1 10) ,但是这个临时文件描述符和常规文件描述符( "foo.txt" )之间有什么区别,这会导致子shell执行的行为不同?
  • 如何实现将 "foo.txt" 重定向到子 shell 的相同行为,但没有临时文件 - 无需实际创建文件。
  • 最佳答案

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

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

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

    还可以尝试:
    (head -1; tail -1) < <(cat /usr/share/dict/words)
    

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

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

    关于bash - 子shell IO重定向,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18982611/

    10-16 11:07