Bash

如何在不關閉標準輸入/標準輸出的情況下關閉命名文件描述符?

  • April 17, 2021
exec {ec}< <(echo "puts 'hello'") && sudo ruby /proc/$$/fd/${ec}

一旦我關閉它

exec <&"${ec}"-

外殼退出。

在另一種情況下,我創建了這個文件描述符:

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

然後我關閉它exec >&${gr}-,現在當我執行一個簡單的命令時ls,什麼都沒有列印。

我可以做ls >&2,果然它顯示了一些東西,但顯然標準輸出現在是 MIA。


我仍在學習所有這些文件描述符業務的工作原理,並希望得到一些指導。謝謝。

Bash的手冊說

如果>&-or<&-前面有,則varname{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。

同樣,exec >&${gr}-(假設$gr不是 IFS 拆分,因為您忘記了引號並且bash仍然在重定向中拆分 + glob)將 stdout 重定向到儲存在$gr(close $gr) 中的 fd。任何進一步的正常輸出,例如來自ls程序替換和grep. 因此,ls可能不會產生任何可見的輸出,但echo hello應該。

您要修改的 fd 編號首先出現在重定向中,預設為 stdin ( 0) for<和 stdout ( 1) for >

引用自:https://unix.stackexchange.com/questions/645500