ファイル記述子が有効かどうかをテスト(入力用)

ファイル記述子が有効かどうかをテスト(入力用)

質問に「ファイル記述子が有効かどうかをテストする「ファイル記述子が開いているかどうかをテストするテストを探しています。

答えはすべてファイル記述子が開いているかどうかをテストすることに焦点を当てています。出力しかし、ファイル記述子が開いているかどうかをテストする方法入力する

これは他の質問に対する回答のコメントスレッドに現れ、答えは次のように説明されています。

if [ -n "$1" ]; then
    # read input from file "$1" (we're assuming it exists)
elif [ ! -t 0 ]; then
    # read input from standard input (from pipe or redirection)
else
    # no input given (we don't want to read from the terminal)
fi

問題は、ファイル記述子が開いている場合はテストが[ ! -t 0 ]真であることです。-tそして端末に関連付けられています。テストがfalseの場合、記述子は次のようになります。誰でも閉じているか、端末に接続されていません(つまり、パイプまたはリダイレクトから読み取っています)。したがって、テストは[ ! -t 0 ]ファイル記述子が有効であることを保証しません。

有効か(read文句を言わないように)、またはオフになっているかどうかを確認するにはどうすればよいですか?

ベストアンサー1

read(fd, 0, 0)Cでは、またはを使用して簡単に確認できます(fcntl(fd, F_GETFL) & O_WRONLY) == 0。標準ユーティリティをだましてこの操作を実行することはできないため、ここにいくつかの考えられる解決策があります。

Linuxでは、以下を使用できます/proc/PID/fdinfo/FD

if [ ! -d "/proc/$$/fd/$fd" ] && grep -sq '^flags.*[02]$' "/proc/$$/fdinfo/$fd"; then
    echo "$fd" is valid for input
fi

OpenBSD と NetBSD では 0 で/dev/fd/FD使用できます。dd

if dd if=/dev/fd/3 count=0 3<&"$fd" 2>/dev/null; then
    echo "$fd" is valid for input
fi

FreeBSDでは、基本的に最初の3つのfdのみが提供されます/dev/fdfdescfs(5)/dev/fd

if (dd if=/dev/fd/0 count=0 <&"$fd") 2>/dev/null; then
    echo "$fd" is valid for input
fi

メモ:

一部のシステムではbashエミュレートされるため、/dev/fd/FD同じ警告が適用されるcat </dev/fd/7ことがあります。cat /dev/fd/7gawk

read(2)長さが0(またはフラグに長さがないopen(2))AはO_TRUNCいいえアクセス時間やその他のタイムスタンプを更新してください。

Linuxでは、read(2)ディレクトリが開いていても常に失敗します。いいえバナーO_DIRECTORY。他のUnixシステムでは、ディレクトリを他のファイルのように読み取ることができます。

これ基準dd count=0ブロックをコピーしてはいけないかどうかは指定されません。みんなgddファイルからのブロック:前者はGNU dd()とdd* BSDの動作です。

おすすめ記事