回答:
文字通りに回答するには、開いているすべてのファイル記述子を閉じますbash
。
for fd in $(ls /proc/$$/fd); do
eval "exec $fd>&-"
done
ただし、シェルが入力および出力に必要とする基本的なファイル記述子を閉じるため、これは実際には良い考えではありません。これを行うと、実行するプログラムはいずれも、端末に出力を表示しません(tty
デバイスに直接書き込む場合を除く)。私のテストで実際にstdin
(exec 0>&-
)を閉じると、対話型シェルが終了するだけです。
実際に探しているのは、シェルの基本操作の一部ではないすべてのファイル記述子を閉じることです。これらはの0 stdin
、の1、stdout
およびの2ですstderr
。これに加えて、いくつかのシェルは他のファイル記述子をデフォルトで開いているようにも見えます。bash
たとえば、255(また、端末I / Oのため)とを持っているdash
と私は10ポイント/dev/tty
ではなく、特定のよりtty
/ pts
デバイス端末が使用しています。で0、1、2、255以外のすべてを閉じるにはbash
:
for fd in $(ls /proc/$$/fd); do
case "$fd" in
0|1|2|255)
;;
*)
eval "exec $fd>&-"
;;
esac
done
eval
変数に含まれているファイル記述子をリダイレクトするときにも必要です。bash
変数が展開されない場合は、それをコマンドの一部と見なします(この場合exec
、コマンド0
または1
ファイル記述子を閉じようとします)。
注:(ls
たとえば/proc/$$/fd/*
)の代わりにグロブを使用すると、グロブの追加のファイル記述子が開くようにls
見えるため、ここでの最良の解決策のようです。
の移植性の/proc/$$/fd
詳細については、ファイル記述子リンクの移植性を参照してください。場合/proc/$$/fd
の代替で利用できない場合、ドロップされ$(ls /proc/$$/fd)
使用は、lsof
(それが利用可能な場合)であろう$(lsof -p $$ -Ff | grep f[0-9] | cut -c 2-)
。
/proc
Linuxでのみ使用できます。
/proc/PID/fd
はあまり移植性がないと言ったらあなたは正しいでしょう。しかし、それ/proc
がLinuxでのみ利用可能であると言うことは正しい説明ではありません。
<&-
フォームを使用していますが、必要なものは異なりますか?
「eval」をまったく使用しない別の方法は、次の形式を使用することです。
$ exec {var_a}>> file.txt
$ echo $var_a
10
$ ls -l /proc/self/fd/10
l-wx------ 1 0 0 64 Dec 11 18:32 /proc/self/fd/10 -> /run/user/0/tmp/file.txt
$ echo "aaaaa" >&$var_a
$ cat file.txt
aaaaa
$ exec {var_a}>&-
$ ls /proc/self/fd/10
ls: cannot access '/proc/self/fd/10': No such file or directory
いいえ。カーネルは一度に1つのFDしか閉じることができず、bashにはFDの「グループコマンド」はありません。
for fd in $(ls -1 /proc/27343/fd); do echo exec $fd">&"-; done
削除echo
および"
テストした後。
これがシェル自体ではなくコマンドを実行する場合は、を使用できますnohup
。
>&-
パラメータにすることはできません。リダイレクトは、パラメーター展開の前に解析されます。
exec {fd}>&-
動作します。