Seseorang dapat memecahkan masalah dengan cara berikut:
cat file | some_sed_command | tee file >/dev/null
Tidak ada .
Kemungkinan file
drop akan terpotong, tetapi tidak ada jaminan cat file | some_sed_command | tee file >/dev/null
tidak akan terpotong file
.
Itu semua tergantung pada perintah mana yang diproses terlebih dahulu, sebagai lawan dari apa yang diharapkan, perintah dalam pipa tidak diproses dari kiri ke kanan . Tidak ada jaminan tentang perintah mana yang akan dipilih pertama, jadi orang mungkin juga menganggapnya sebagai dipilih secara acak dan tidak pernah bergantung pada shell tidak memilih yang menyinggung.
Karena peluang untuk perintah yang salah untuk dipilih pertama di antara tiga perintah lebih rendah daripada peluang untuk perintah yang melanggar untuk dipilih pertama di antara dua perintah, kecil kemungkinannya file
akan dipotong, tetapi itu masih akan terjadi .
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
Jadi jangan pernah gunakan sesuatu seperti cat file | some_sed_command | tee file >/dev/null
. Gunakan sponge
seperti yang disarankan Oli.
Sebagai alternatif, untuk lingkungan yang lebih keras dan / atau file yang relatif kecil seseorang dapat menggunakan string di sini dan substitusi perintah untuk membaca file sebelum perintah apa pun dijalankan:
$ cat file
foo
bar
$ for ((i=0; i<100; i++)); do <<<"$(<file)" sed 's/bar/baz/' >file; done
$ cat file
foo
baz