为何Bash中进程替换流仅能被读取一次?
为什么进程替换的流只能被读取一次?
你编写了如下脚本演示该问题:
#!/bin/bash cat_then_tac() { echo cat cat "$1" echo tac tac "$1" echo end } seq 3 > file1 echo echo using proper file: works as expected cat_then_tac file1 echo echo using process substitution: stream is somehow consumed upon first use and tac has nothing to work on cat_then_tac <(seq 3) rm file1
脚本运行输出:
using proper file: works as expected cat 1 2 3 tac 3 2 1 end using process substitution: stream is somehow consumed upon first use and tac has nothing to work on cat 1 2 3 tac end
原因解释
- 普通文件(比如示例中的
file1)属于可随机访问的存储介质:每次打开文件时,系统会将读取偏移量重置到文件开头,因此cat和tac都能完整读取文件内容。 - 进程替换
<(seq 3)的本质是匿名管道:bash会创建一条单向数据流,把seq 3的输出定向到这个管道中。管道的内容是一次性的,读取过的数据会被直接丢弃,不支持回退或重复读取。当第一次cat "$1"读完管道内所有数据后,后续tac "$1"再读取时,管道已经没有剩余数据,自然输出为空。
规避方案
正如你提到的,要重复使用流内容,必须先将数据持久化:
- 保存到临时文件:
temp=$(mktemp) seq 3 > "$temp" cat_then_tac "$temp" rm "$temp"
- 保存到变量后重新生成流:
content=$(seq 3) cat_then_tac <(echo "$content")
内容的提问来源于stack exchange,提问作者Alex Escodro
相关产品推荐
相关产品推荐

