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)
问题:
我不确定要命名的是什么<(seq 1 10),但这个临时文件描述符和常规文件描述符("foo.txt")之间的区别是什么导致子shell执行的行为不同?
如何在不实际创建文件的情况下实现将a重定向"foo.txt"到子shell但没有临时文件的相同行为.
这只是一个缓冲问题.尝试:
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只消耗输入的第一页,尾部看到数据的最后一行.
您看到的行为定义不明确,因为没有标准规定允许消耗多少数据头.如果替换head为sh -c 'read line; echo "$line"',则在所有情况下都将获得所需的行为.(或者编写自己的工具来提供head您想要的行为- 打印固定数量的行而不消耗更多行.)