この質問は、ファイル記述子を読み書きすることに関するものです。次の例をご覧ください。
#!/bin/sh
file='somefile'
# open fd 3 rw
exec 3<> "$file"
# write something to fd 3
printf "%s\n%s\n" "foo" "bar" >&3
# reading from fd 3 works
cat "/proc/$$/fd/3"
# only works if the printf line is removed
cat <&3
exit 0
スクリプトは以下を出力します。
foo
bar
予想出力:
foo
bar
foo
bar
ファイル記述子を開いて書き込むことに成功しました。読書も同じだproc/$$/fd/3
。しかし、これは持ち運びが容易ではない。cat <&3
何も出力しません。ただし、ファイルディスクリプタが作成されていない場合(たとえば、その行のコメントアウトを削除するなど)はprintf
機能します。
なぜ動作しないのか、cat <&3
そしてポータブルファイル記述子(POSIXシェル)から内容全体をどのように読み取ることができますか?
ベストアンサー1
cat <&3
ファイルの終わりに達するまで、ファイルから読み取る操作を正確に実行します。呼び出すと、ファイル記述子のファイルの場所は最後に離れた場所、つまりファイルの終わりです。 (読み取りと書き込みのための別の場所ではなく、1つのファイルの場所があります。)
cat /proc/$$/fd/3
同じことはしませんcat <&3
。別の記述子で同じファイルを開きます。各ファイル記述子には固有の場所があり、ファイルを読み取るために開くと場所が0に設定されるため、このコマンドはファイル全体を印刷し、スクリプトには影響しません。
作成した内容を再度読み取るには、ファイルを再度開くか、ファイル記述子を巻き戻す必要があります(たとえば、場所を0に設定)。 POSIXシェルとほとんどのsh実装にはこれを行う組み込み方法はありません(ksh93に1つあります)。追求すべきユーティリティは1つだけです。dd
しかし、今後のみナビゲートできます。 (これから飛び越えることができる他のユーティリティがありますが、これは役に立ちません。)
唯一のポータブルソリューションは、ファイル名を覚えており、必要に応じて何度も開くことだと思います。ファイルが通常のファイルではない場合は、以前のバージョンを確認できない場合がありますのでご注意ください。