ファイル記述子とシェルスクリプト

ファイル記述子とシェルスクリプト

シェルスクリプトでファイル記述子を使用する方法を理解するのに問題があります。

私は次のいくつかの基本を知っています。

exec 5 > /tmp/foo

したがって、fd 5 は書き込み用に 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

fdを閉じることについて私が理解したところによると&5、各呼び出しの後に出力がどのように正常にリダイレクトされることができますか?

以下はパスタのレプリカです。ここ

単純ではなく、これを使用すると速度が速くなると主張しますecho $a > fileが、理解できません。まともなチュートリアルへのリンクを提供していただきありがとうございます。私のGoogleの能力が私に失敗したようです。

答え1

まず、ファイル記述子が書き込み用か読み取り用かによって、close構文はまたは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リダイレクトの例

答え2

開いている各ファイルにはファイル記述子が割り当てられます。 stdinのファイル記述子は0、stdoutは1、
stderrは2です。別のファイルを開くには、記述子3〜9も予約されています。

例えば

exec 3>&1 4>&2
exec 1>  /proc/1/fd/1 2>&1

3>&1新しいファイル記述子を作成し、それを1(STDOUT)にリダイレクトし、 4>&2新しいファイル記述子を2(STDERR)にリダイレクトします。

1> /proc/1/fd/1ソケットファイル記述子を使用すると、 2>&1このファイル記述子の内容はすべて1(STDOUT)にリダイレクトされます。

私も最近知った内容だと不足している点があれば指摘してください。

execを使用したリダイレクトとファイル記述の使用に関するリファレンス https://www.linuxtopia.org/online_books/advanced_bash_scripting_guide/x13082.html

関連情報