子shell IO重定向

Rub*_*ens 8 bash redirect file-descriptor subshell

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

$ seq 1 10 > "foo.txt"
Run Code Online (Sandbox Code Playgroud)

我正在尝试读取文件的第一行和最后一行,并且我开始将文件重定向到子shell,以便命令列表将按顺序使用该文件 - 每个命令都使用来自该点的输入最后一个命令离开了,我想:

$ (head -1; tail -1) < "foo.txt"
1
10
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试使用临时文件描述符,输出不一样:

$ (head -1; tail -1) < <(seq 1 10)
1
Run Code Online (Sandbox Code Playgroud)

问题:

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

  2. 如何在不实际创建文件的情况下实现将a重定向"foo.txt"到子shell但没有临时文件的相同行为.

Wil*_*ell 8

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

cat foo.txt | ( head -1; tail -1)
Run Code Online (Sandbox Code Playgroud)

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

还试试:

(head -1; tail -1) < <(cat /usr/share/dict/words)
Run Code Online (Sandbox Code Playgroud)

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

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

  • +1非常好的解释.但是,OP询问是否可以在没有任何临时文件的情况下获得此类行为.是吗?我的测试没有成功. (2认同)