子shell IO重定向

时间:2013-09-24 13:11:43

标签: bash redirect file-descriptor subshell

给定一个文件"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. 如何在不实际创建文件的情况下实现将"foo.txt"重定向到子shell但没有临时文件的相同行为。

    < / LI>

1 个答案:

答案 0 :(得分:7)

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

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

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

还可以尝试:

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

这里,head仅消耗输入的第一页,尾部查看数据的最后一行。

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