私はこのファイルとfdを持っています:exec 88<>abc
なぜ
$ sed -i "s/cd/II/g" /proc/$$/fd/88
sed: couldn't open temporary file /proc/26194/fd/sedS1D1FT: No such file or directory
しかし、これはうまくいきます:
$ cat /proc/self/fd/88 | sed "s/cd/II/g"
abIIefg
その後、これは機能しません。
$ (cat /proc/self/fd/88 | sed "s/cd/II/g") > /proc/self/fd/88
/proc/self/fd/88
これにより空になります。
答え1
sed -i
ファイルは実際には「その場で」編集されません。出力を一時ファイルにリダイレクトし、一時ファイルの名前を変更するか、元のファイルに移動するように機能します。
これにより、途中で問題が発生しても元のファイルが失われることはありません。
さらに悪いことは、sed
(たとえばvim
)元のファイルと同じディレクトリに一時ファイルを作成しようとすることです。
ファイル/proc
システムは人工、その中にファイルを作成または移動できないため、対応するエラーが発生します。ただし、sed
一時ファイルがから作成されても、最後の/tmp
操作(一時ファイルを元のファイルに名前変更)はまだ失敗します。
sed -i
ロータリー方式で試すことができます。
$ ised(){ for a; do :; done; t=`mktemp` && sed "$@" > "$t" && cat "$t" > "$a" && rm "$t"; }
$ ised s/cd/II/g /proc/$$/fd/88
ファイル名は常にised
。
これは一貫性の保証を破りますsed -i
。とは異なり、cat in > out
作業はrename("in", "out")
原子的ではありません。途中で停止すると、out
ファイルは切り捨てられます。
答え2
実際のファイルがまだ存在すると仮定すると、これはより良い可能性があります(ただし、実際のファイルを変更するので注意して使用してください)。
sed -i s/cd/II/g "$(realpath "/proc/$$/fd/88")"
〜のようにモスビーノート、の結果がrealpath /proc/$$/fd/88
削除された場合、この操作は何の効果もありません。例:
exec 7>/tmp/junk; echo yes >&7; rm /tmp/junk;
cat /proc/$$/fd/7; cat "$(realpath "/proc/$$/fd/7")"
出力(にもかかわらず/tmp/ジャンク存在しない)、最初の行標準出力、ライン2~標準エラーエラー率:
yes
cat: '/tmp/junk (deleted)': No such file or directory