ファイル記述子の寿命はどれくらいですか?


11

ここで説明するように、リダイレクトopen()はファイルへの書き込みに使用します。シェルで作成された内部(?)ファイル記述子があり、必要なときに使用されます。

内部記述子は、スクリプトの全期間またはシェルの存続期間に対して作成されますか?しばらくすると破壊されますか?

特に、シェル自体が組み込みの操作のために開くファイルのファイル記述子を意味します。各操作で記述子が作成され、ファイルが開かれますか?それらはどれくらいの期間保持されますか?例:

#!/bin/bash
>>x echo something
...do many other things not related to the file x
>>x echo something more

最初の記述子インスタンスは、2番目の操作まで保持されますか?

ターミナルで使用するシェルはどうですか?1つのセッションを数日間、場合によっては数週間開いたままにすることがあります。シェル組み込みで操作したすべてのファイルの記述子はまだ保持されますか?

回答:


4

簡単に言うと、シェルは、コマンドが完了するとすぐに、リダイレクトに関連するファイル記述子をほぼ確実に閉じます。


詳細: POSIXのリダイレクトを介して開かれたファイルを閉じることに関する明示的な言及はありません(私の知る限り)。しかし、それらをすぐに閉じないことは、あまり役に立ちません。

コマンドが開始される環境ルールでは、追加のファイル記述子を渡すことができません。シェルは、必要のないコマンドを開始するときに保存されている余分なfdを閉じるように注意する必要があります。

通常の> filename出力リダイレクトでは、ファイル記述子が保存されている場合でも、各コマンドの開始時にファイルを切り捨てる必要があります。そして、すべての関係のファイルの名前を変更またはその間に削除された場合は保存されたファイルディスクリプタは、間違ったファイルを指します。

たとえば、最初echoに開いたfdを開いたままにして、2番目のfd をそのまま使用すると、これは正しく動作しません。

echo foo >> x; mv x y; echo bar >> x

外部プログラムの起動に使用される通常のfork + execモデルを使用すると、コマンドの終了時にファイルを自動的に閉じることも非常に簡単になります。シェルは、実際のコマンドで子を置き換えるためfork()に呼び出す前に、最初に子プロセスで必要なファイルを開くだけで済みますexec()。子プロセスが終了すると、それによって開かれたファイルはすべて自動的に閉じられます。


ではawk、しかし、出力のリダイレクトのための構文は、シェルに似ていますが、明示的に閉じない限り開かれたファイルは、スクリプトが終了するまで開いたままにしています。これは一foo度だけ開かれ、印刷の間でも切り捨てられません:

awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'

6

終了すると閉じられます。シェルは、実行するコマンドごとに3つのファイル記述子0、1、2を作成します。これらは単なる数値であり、数値は再利用されます。シェルは記述子を再利用する前にファイルを閉じます。

ファイル記述子は他のプロセスにも渡されます。そして、あなたがバックグラウンドでプロセスを持っているなら、それはまだファイル記述子を持っています。

この例ではを使用しています3>&1。これは、ファイル記述子3が記述子1が現在参照しているファイルを参照することを意味します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.