Chcę wygenerować posortowaną listę ze wszystkimi 8-cyfrowymi liczbami - od 00000000 do 99999999. Wpisałem powłokę:
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
odpowiedzią jest
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
99998890
Dlaczego dostałem te trzy błędy i źle sformatowany wynik.txt?
używam
GNU bash, wersja 4.4.12 (1) -release (x86_64-pc-linux-gnu)
Debian GNU / Linux 9.6 (odcinek)
Jądro Linux: 4.19.0 # 2 SMP czw. 1 lis 15:31:34 EET 2018 x86_64 GNU / Linux
seq -w 0 99999999
.}
) działa poprawnie. @ GAD3Rkonsole
okna. Taka zmiana rozmiaru jest prawie wystarczająca w moim przypadku, ale nie jest konieczna.| tee result.txt
i nadal pojawia się błąd./bin/echo
w moim przypadku) zamiastecho
wbudowanego powoduje, że funkcja jest odporna (lub przynajmniej mniej podatna) na ten problem.Odpowiedzi:
Konkretny
write error: Interrupted system call
błąd jest generowany, gdy rozmiar okna konsoli zmienia się podczas wykonywania skryptu.Robiąc:
uniknie tego.
Zauważ, że a
Będzie zarówno szybszy, jak i pozwoli uniknąć
SIGWINCH
problemu.źródło
Właściwie jest to bug [1] w
bash
, a to nie zdarza się tylkoSIGWINCH
, ale także od jakiegokolwiek sygnału dla których pułapka została ustalona:Dzieje się tak, ponieważ
bash
nie albo) ustawić jego obsługi sygnałów zSA_RESTART
(z wyjątkiemSIGCHLD
obsługi), lub b) obsłużyćEINTR
podczas wywoływaniawrite()
wprintf
iecho
poleceń wbudowanych.EINTR
(„Przerwane wywołanie systemowe”) nie jest sposobem wskazania błędu, ale hackem, który pozwala programiście połączyć blokujące odczyty / zapisy / etc z obsługą sygnałów w głównej pętli. Nigdy nie powinien być wyciekany do użytkownika.Ten błąd nie pojawia się zbyt często, ponieważ uzyskanie odpowiednich warunków: wyczyn
write()
powinno to być zrobione przez wbudowane (nie przez zewnętrzne polecenie), powinno wypełnić bufor potoku (czytnik z drugiej strony koniec powinien być znacznie wolniejszy lub w ogóle nie czytać z potoku, ale wciąż żywy ), a skrypt powinien używać pułapek lub należy zmienić rozmiar okna terminala.A ze względu na różnorodne artefakty implementacji wpływa to tylko na przerwane
write()
s, nieread()
s lubopen()
s (jak np. Blokowanieopen()
nazwanego potoku / fifo).[1] forma tego została już zgłoszona jakiś czas temu.
źródło