Я хочу создать отсортированный список со всеми 8-значными числами - от 00000000 до 99999999. Я набрал в оболочке:
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
ответ
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
99998890
Почему я получил эти три ошибки и искаженный файл result.txt?
я использую
GNU bash, версия 4.4.12 (1) -релиз (x86_64-pc-linux-gnu)
Debian GNU / Linux 9.6 (растянутая)
Ядро Linux: 4.19.0 # 2 SMP четверг, 1 ноября 15:31:34 EET 2018 x86_64 GNU / Linux
seq -w 0 99999999
.}
) работает правильно. @ GAD3Rkonsole
окна. Такое изменение размера почти достаточно в моем случае, но не обязательно.| tee result.txt
, и все еще получить ошибку./bin/echo
в моем случае) вместоecho
встроенного делает функцию невосприимчивой (или, по крайней мере, менее склонной) к этой проблеме.Ответы:
Конкретная
write error: Interrupted system call
ошибка генерируется при изменении размера окна консоли во время выполнения скрипта.Делать:
буду избегать этого.
Обратите внимание, что
Будет и быстрее, и позволит избежать
SIGWINCH
проблемы.источник
Это на самом деле ошибка [1] в
bash
, и это происходит не толькоSIGWINCH
, но и для любого сигнала, для которого была установлена ловушка:Это происходит потому, что
bash
не удается либо a) установить свои обработчики сигналов с помощьюSA_RESTART
(кромеSIGCHLD
обработчика), либо b) обработатьEINTR
при вызовеwrite()
вprintf
иecho
встроенные функции.EINTR
(«Прерванный системный вызов») - это не способ обозначить состояние ошибки, а взлом, который позволяет программисту комбинировать блокировку чтения / записи / и т. Д. С обработкой сигналов в основном цикле. Он никогда не должен быть передан пользователю.Эта ошибка появляется не слишком часто, потому что это довольно сложная задача - установить правильные условия: это
write()
должно быть сделано встроенным (а не внешней командой), оно должно заполнить буфер канала (читатель на другом конец должен быть намного медленнее или вообще не читать из канала, но все еще жив ), и сценарий должен использовать ловушки или окно терминала должно быть изменено.А из-за разнообразных артефактов реализации это влияет только на прерванные
write()
s, а неread()
s илиopen()
s (как, например, блокированиеopen()
именованного канала / fifo).[1] форма об этом уже сообщалось некоторое время назад.
источник