ここ で説明したように、リダイレクトはopen()
を使用してファイルに書き込みます。シェルで作成された内部(?)ファイル記述子があり、必要に応じて使用されます。
内部記述子は、スクリプトの全期間またはシェルの存続期間に対して作成されますか?しばらくすると破壊されますか?
特にシェル自体がビルトインの操作のために開くファイルのファイル記述子を意味します。各操作で記述子が作成され、ファイルが開かれますか?それらはどのくらいの期間保管されますか?例:
#!/bin/bash
>>x echo something
...do many other things not related to the file x
>>x echo something more
最初の記述子インスタンスは2番目の操作まで保持されますか?
端末で使用するシェルはどうですか? 1つのセッションを数日間、場合によっては数週間開いたままにすることもあります。 Shellビルトインで操作したすべてのファイルの記述子を保持しますか?
簡単:シェルは、コマンドが完了した直後に、リダイレクトに関連するファイル記述子をほぼ確実に閉じます。
詳細:redirections で開かれたファイルをPOSIXで閉じることについての明確な言及はありません(私が見る限り)。しかし、それらをすぐに閉じないことは、あまり役に立ちません。
コマンドが開始される環境のルール 追加のファイル記述子を渡すことはできません。シェルは、保存されていないはずのコマンドを開始するときに、保存されている余分なfdを閉じるように注意する必要があります。
通常の_> filename
_出力リダイレクトでは、ファイル記述子が保存されている場合でも、各コマンドの開始時にファイルを切り捨てる必要があります。また、any保存されたファイル記述子は、その間に該当するファイルの名前が変更または削除された場合、誤ったファイルを指します。
たとえば、最初のecho
に対して開いたfdを開いたままにして、2番目にそのまま使用した場合、これは正しく動作しません。
_echo foo >> x; mv x y; echo bar >> x
_
外部プログラムの起動に使用される通常のfork + execモデルでは、コマンドの終了時にファイルを自動的に閉じることも非常に簡単です。シェルは、最初にfork()
を実行し、exec()
を呼び出して子を実際のコマンドに置き換える前に、子プロセスで必要なファイルを開くだけです。子プロセスが終了すると、それによって開かれたファイルはすべて自動的に閉じられます。
ただし、awk
では、出力リダイレクトの構文はシェルと似ていますが、開いているファイルはスクリプトが終了するまで開いたままになります、明示的に閉じられていない限り。これはfoo
を1度だけ開き、印刷間で切り捨てることもありません。
_awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'
_
終了すると閉じられます。シェルは、実行するコマンドごとに3つのファイル記述子0、1、2を作成します。これらは単なる数値であり、数値は再利用されます。シェルは、記述子を再利用する前にファイルを閉じます。
ファイル記述子は他のプロセスにも渡されます。また、バックグラウンドでプロセスを実行している場合でも、ファイル記述子が残ります。
この例では3>&1
、これは、ファイル記述子3が記述子1が現在参照しているファイルを参照することを意味します。