Sorunu şu şekilde çözebiliriz:
cat file | some_sed_command | tee file >/dev/null
Hayır .
Şansı file
düşürme şansı olacak, ancak cat file | some_sed_command | tee file >/dev/null
kısalmayacağının garantisi yok file
.
Her şey, ilk önce hangi komutun işleneceğine bağlıdır, birinin ne beklediğinin aksine , bir borudaki komutlar soldan sağa işlenmez . İlk olarak hangi komutun seçileceğine dair bir garanti yoktur, bu yüzden biri rastgele seçildiğini düşünebilir ve rahatsız edici olanı seçmeyen kabuğa asla güvenemez.
Üç komut arasında ilk olarak rahatsız edici komutun seçilme şansı, iki komut arasında ilk olarak rahatsız edici komutun seçilme şansından daha düşük olduğundan, kesilme olasılığı düşüktür file
, ancak yine de gerçekleşecektir .
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
Bu yüzden asla böyle bir şey kullanmayın cat file | some_sed_command | tee file >/dev/null
. sponge
Oli'nin önerdiği gibi kullanın .
Alternatif olarak, daha yoğun ortamlar ve / veya nispeten küçük dosyalar için burada herhangi bir komut çalıştırılmadan önce dosyayı okumak için burada bir dize ve bir komut değişikliği kullanılabilir:
$ cat file
foo
bar
$ for ((i=0; i<100; i++)); do <<<"$(<file)" sed 's/bar/baz/' >file; done
$ cat file
foo
baz