从FD 3读取指向临时文件时的“错误文件描述符”

Jon*_*nah 6 bash

我的问题是受此答案的启发。

考虑以下脚本:

tmpfile=$(mktemp)
exec 3>"$tmpfile"
rm "$tmpfile"

>&3 cat <<EOS
line 1
line 2
line 3
EOS

cat <&3
Run Code Online (Sandbox Code Playgroud)

您可以在这里在线玩

我希望它能打印出3行,但实际上我收到“错误文件描述符”错误。

为什么上述方法不起作用?如何对其进行更改才能做到?

注意:即使删除第三行,该错误仍然存​​在rm "$tmpfile"

che*_*ner 11

您仅打开文件描述符3进行写入,而不是读取。将该行更改为

exec 3<>"$tmpfile"
Run Code Online (Sandbox Code Playgroud)

错误的文件描述符错误将消失。

但是,cat <&3仍然不会产生任何输出,因为文件指针在上次写入之后仍位于文件的末尾。您需要返回到文件的开头以输出您刚刚编写的内容,但是bash不提供查找的方法。最好的办法是通过关闭并重新打开文件描述符3或通过打开另一个文件描述符来重新打开文件以进行读取。

由于目标是在删除唯一链接后读取文件,因此您必须在删除文件之前打开另一个文件描述符以进行读取。

tmpfile=$(mktemp)
exec 3> "$tmpfile"
exec 4< "$tmpfile"

rm "$tmpfile"

>&3 cat <<EOS
line 1
line 2
line 3
EOS

cat <&4
Run Code Online (Sandbox Code Playgroud)

尽管3和4都引用同一个文件,但是它们各自维护一个单独的文件指针。无需打开3进行阅读和写作。您可以在描述符3上写入文件,然后从描述符4读取内容。

  • 在删除文件之前添加`exec 4&lt; "$tmpfile"`;然后在文件描述符 3 上写入后 `cat &lt;&amp;4` 将显示内容,因为 4 的文件指针还没有前进。 (2认同)