次の方法で問題を解決できます:
cat file | some_sed_command | tee file >/dev/null
いいえ。
確率file
は切り捨てられますが、切り捨てられないという保証cat file | some_sed_command | tee file >/dev/null
はありませんfile
。
予想されるのとは対照的に、パイプ内のコマンドは左から右に処理されません。どのコマンドが最初に選択されるかについての保証はありません。そのため、ランダムに選択されたと考えて、問題のコマンドを選択しないシェルに依存することはできません。
3つのコマンドの間で最初に問題のコマンドが選択される可能性は、2つのコマンドの間で最初に問題のコマンドが選択される可能性よりも低いため、file
切り捨てられる可能性は低くなりますが、引き続き発生します。
script.sh
:
#!/bin/bash
for ((i=0; i<100; i++)); do
cat >file <<-EOF
foo
bar
EOF
cat file |
sed 's/bar/baz/' |
tee file >/dev/null
[ -s file ] &&
echo 'Not truncated' ||
echo 'Truncated'
done |
sort |
uniq -c
rm file
% bash script.sh
93 Not truncated
7 Truncated
% bash script.sh
98 Not truncated
2 Truncated
% bash script.sh
100 Not truncated
したがって、のようなものは決して使用しないでくださいcat file | some_sed_command | tee file >/dev/null
。sponge
Oliの提案どおりに使用します。
別の方法として、より厳しい環境や比較的小さなファイルの場合、コマンドが実行される前にhere文字列とコマンド置換を使用してファイルを読み取ることができます。
$ cat file
foo
bar
$ for ((i=0; i<100; i++)); do <<<"$(<file)" sed 's/bar/baz/' >file; done
$ cat file
foo
baz