シェルスクリプトでファイル記述子をどのように使用するかを理解するのに非常に苦労しています。
などの基本を知っています
exec 5 > /tmp/foo
したがって、fd5は書き込み用にfooにアタッチされます。
exec 6 < /tmp/bar
…読むために。
exec 5>&-
…fdを閉じます。
さて、これは何をしますか?
#!/bin/bash
exec 5 > /tmp/foo
exec 6 < /tmp/bar
cat <&6 | while read a
do
echo $a >&5
done
私が理解しているように&5
fdを閉じるので、各呼び出し後に出力はどのように正常にリダイレクトされますか?
これはコピーパスタです:ここ
単純なecho $a > file
でこれを使用すると主張しています それをはるかに速くするでしょう、しかし私は理解できません。まともなチュートリアルへのリンクをいただければ幸いです。私はグーグルパワーが私を失敗させているようです。
承認された回答:
まず、閉じるための構文が5>&-
であることに注意してください または6<&-
、ファイル記述子が書き込み用または読み取り用のどちらで読み取られているかによって異なります。そのブログ投稿にはタイプミスまたはフォーマットの不具合があるようです。
コメントしたスクリプトは次のとおりです。
exec 5>/tmp/foo # open /tmp/foo for writing, on fd 5
exec 6</tmp/bar # open /tmp/bar for reading, on fd 6
cat <&6 | # call cat, with its standard input connected to
# what is currently fd 6, i.e., /tmp/bar
while read a; do #
echo $a >&5 # write to fd 5, i.e., /tmp/foo
done #
ここで締めくくりはありません。この単純な例では、すべての入力と出力が同じ場所に移動するため、追加のファイル記述子を使用する必要はありません。あなたは書くことができます
cat </tmp/bar |
while read a; do
echo $a
done >/tmp/foo
明示的なファイル記述子を使用すると、複数のファイルに順番に書き込む場合に役立ちます。たとえば、データをデータ出力ファイルに出力し、データをログファイルに記録し、場合によってはエラーメッセージも出力するスクリプトについて考えてみます。つまり、3つの出力チャネルがあります。1つはデータ用、1つはログ用、もう1つはエラー用です。出力用の標準記述子は2つしかないため、3番目が必要です。 exec
を呼び出すことができます 出力ファイルを開くには:
exec >data-file
exec 3>log-file
echo "first line of data"
echo "this is a log line" >&3
…
if something_bad_happens; then echo error message >&2; fi
exec >&- # close the data output file
echo "output file closed" >&3
効率に関する注意は、次のようにループ内にリダイレクトがある場合に発生します(最初はファイルが空であると想定します):
while …; do echo $a >>/tmp/bar; done
各反復で、プログラムは/tmp/bar
を開きます 、ファイルの最後までシークし、データを追加してファイルを閉じます。ファイルを一度だけ開く方が効率的です:
while …; do echo $a; done >/tmp/bar
異なる時間に複数のリダイレクトが発生している場合は、exec
を呼び出します ブロックをリダイレクトでラップするのではなく、リダイレクトを実行することが便利になります。
exec >/tmp/bar
while …; do echo $a; done
io-redirection
を参照すると、リダイレクトのその他の例がいくつか見つかります。 このサイトのタグ。