如何在不关闭 stdin/stdout 的情况下关闭命名文件描述符?

如何在不关闭 stdin/stdout 的情况下关闭命名文件描述符?
exec {ec}< <(echo "puts 'hello'") && sudo ruby /proc/$$/fd/${ec}

一旦我关闭它

exec <&"${ec}"-

外壳退出。

在另一种情况下,我创建这个文件描述符:

exec {gr}> >(/usr/bin/grep 'hello')

然后我关闭它exec >&${gr}-,现在当我运行像这样的简单命令时ls,不会打印任何内容。

我可以做ls >&2,而且果然它显示了一些东西,但显然标准输出现在是 MIA。


我仍在学习所有这些文件描述符业务的工作原理,并且需要一些指导。谢谢。

答案1

Bash 的手册说:

如果>&-<&-前面有{varname},则值变量名定义要关闭的文件描述符。

所以,它是exec {fd}>&-(或{fd}<&-)关闭它。

$ exec {fd}>foo.out
$ echo "$fd"
10
$ echo hi >&"$fd"             # works
$ exec {fd}>&-                # close it
$ echo ho >&"$fd"             # doesn't work any more
bash: "$fd": Bad file descriptor
$ cat foo.out
hi     

exec <&"${ec}"-将名为 in 的 fd 移动$ec到 stdin (即使 stdin 成为 fd 的副本$ec,然后关闭 fd $ec)。 shell 现在将其标准输入连接到进程替换,并继续从那里读取输入。但ruby可能已经读取了所有内容,管道只会给出 EOF,退出 shell。

类似地,将 stdout 重定向到存储在(结束)exec >&${gr}-中的 fd 。任何进一步的常规输出,例如 from都会进入进程替换和.因此,可能不会产生任何可见的输出,但应该产生。$gr$grlsgreplsecho hello

尽管像往常一样,$gr这里也应该被引用以避免分词,因为通常IFS可以包含数字。所以最好写成 exec >&"${gr}"-.

您要修改的 fd 编号在重定向中排在第一位,默认值为 stdin ( 0) for<和 stdout ( 1) for >

相关内容