Saya ingin membuat daftar yang diurutkan dengan semua angka 8-digit - dari 00000000 hingga 99999999. Saya mengetikkan shell:
f() {
while IFS="" read -r line; do
for i in {0..9}; do
echo "$line$i";
done;
done
}
echo | f | f | f | f | f | f | f | f | tee result.txt | wc -l
jawabannya adalah
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
99998890
Mengapa saya mendapatkan ketiga kesalahan ini dan result.txt salah bentuk?
saya menggunakan
GNU bash, versi 4.4.12 (1) -release (x86_64-pc-linux-gnu)
Debian GNU / Linux 9.6 (peregangan)
Kernel Linux: 4.19.0 # 2 SMP Kamis 1 Nov 15:31:34 EET 2018 x86_64 GNU / Linux
seq -w 0 99999999
.}
) berfungsi dengan benar. @ GAD3Rkonsole
jendela saya . Mengubah ukuran seperti itu hampir cukup dalam kasus saya, namun tidak perlu.| tee result.txt
, dan masih mendapatkan kesalahan./bin/echo
dalam kasus saya) bukannyaecho
builtin membuat fungsi kebal (atau setidaknya kurang rentan) untuk masalah ini.Jawaban:
write error: Interrupted system call
Kesalahan spesifik dihasilkan ketika ukuran jendela konsol diubah saat skrip dieksekusi.Melakukan:
akan menghindarinya.
Perhatikan bahwa a
Akan lebih cepat dan akan menghindari
SIGWINCH
masalah.sumber
Ini sebenarnya adalah bug [1] di
bash
, dan itu tidak terjadi hanya padaSIGWINCH
, tetapi juga pada sinyal yang perangkap ditetapkan:Hal ini terjadi karena
bash
gagal baik) mengatur penangan sinyal denganSA_RESTART
(kecuali untukSIGCHLD
handler), atau b) menanganiEINTR
saat memanggilwrite()
dalamprintf
danecho
builtin.EINTR
("Panggilan sistem terputus") bukan cara untuk menunjukkan kondisi kesalahan, tetapi peretasan yang memungkinkan programmer untuk menggabungkan pemblokiran read / wrote / etc dengan penanganan sinyal di loop utama. Seharusnya tidak pernah bocor ke pengguna.Bug ini tidak muncul terlalu sering karena itu adalah suatu prestasi untuk mendapatkan kondisi yang tepat: yang
write()
harus dilakukan oleh builtin (bukan oleh perintah eksternal), ia harus mengisi penyangga pipa (pembaca di sisi lain ujungnya harus jauh lebih lambat atau tidak membaca dari pipa sama sekali tetapi masih hidup ), dan skrip harus menggunakan perangkap atau jendela terminal harus diubah ukurannya.Dan karena artefak implementasi yang beragam, ini hanya mempengaruhi
write()
s yang terputus , bukanread()
s atauopen()
s (seperti misalnya pemblokiranopen()
pipa bernama / fifo).[1] formulir ini sudah dilaporkan beberapa waktu lalu.
sumber