在 bash 脚本中;当您多次打开进程 stdout 作为文件名参数时,它会失败

在 bash 脚本中;当您多次打开进程 stdout 作为文件名参数时,它会失败

考虑这个 bash 脚本代码:

#!/bin/bash

function bug_part() {
    cat $1 > sample.first
    cat $1 > sample.second #second time you open file $1, it contains no data
}

bug_part <(echo "TEST")
[ "$(cat sample.first)" != "$(cat sample.second)" ] && echo "THIS IS A BUG" 1>&2 && exit 1
rm sample.first sample.second

你同意我的观点,这个问题是 bash bug 吗?还是Linux的bug?

有谁知道背后究竟发生了什么吗?

答案1

我不认为这是一个错误。您可以读取/写入连接到由以下命令准备的命令的命名管道流程替代只有一次。

答案2

这是你的脚本中的一个错误。tee如果您想要复制只能读取一次的数据,请使用此选项。正如另一个答案所解释的, <(cmd) 创建一个管道,并/dev/fd/62在命令行上放置或类似的内容:

echo <(true)
  /dev/fd/63

另一种替代方案tee是此处字符串:

cmd <<<"$text"

如果您希望 bash 创建一个可查找的 tmp 文件并从中重定向输入。 (不过,我不确定如何将 stdin 倒回到函数内文件的开头。我认为cat /dev/stdin可能会得到相同的文件位置。)

答案3

扩展 @Peter Cordes' 使用tee而不是尝试读取文件(/pipe)两次的建议,这里是该函数的可能重写:

bugless_part() {
    tee sample.first >sample.second <"$1"
}

当运行为 时bugless_part <(echo "TEST"),它将“TEST”放入两个文件中。

相关内容