Quiero generar una lista ordenada con todos los números de 8 dígitos, desde 00000000 hasta 99999999. Escribí en el 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
la respuesta es
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
bash: echo: write error: Interrupted system call
99998890
¿Por qué obtuve estos tres errores y result.txt con formato incorrecto?
yo suelo
GNU bash, versión 4.4.12 (1) -release (x86_64-pc-linux-gnu)
Debian GNU / Linux 9.6 (estiramiento)
Kernel de Linux: 4.19.0 # 2 SMP jue 1 de noviembre 15:31:34 EET 2018 x86_64 GNU / Linux
seq -w 0 99999999
.}
) funciona correctamente. @ GAD3Rkonsole
ventana. Tal cambio de tamaño es casi suficiente en mi caso, pero no es necesario.| tee result.txt
y aún obtener el error./bin/echo
en mi caso) en lugar deecho
incorporado hace que la función sea inmune (o al menos menos propensa) a este problema.Respuestas:
El
write error: Interrupted system call
error específico se genera cuando se cambia el tamaño de la ventana de la consola mientras se ejecuta el script.Haciendo un:
Lo evitaré.
Tenga en cuenta que un
Será a la vez más rápido y evitará el
SIGWINCH
problema.fuente
Esto es en realidad un error [1] en
bash
, y esto no sucede sólo enSIGWINCH
, sino también en cualquier señal para la que se estableció una trampa:Ocurre porque
bash
a) no establece a) sus manejadores de señal conSA_RESTART
(excepto elSIGCHLD
manejador), o b) maneja elEINTR
al llamarwrite()
en los builtinsprintf
yecho
.EINTR
("Llamada de sistema interrumpida") no es una forma de indicar una condición de error, sino un truco que permite al programador combinar el bloqueo de lecturas / escrituras / etc. con el manejo de señales en el bucle principal. Nunca se debe filtrar al usuario.Este error no aparece con demasiada frecuencia porque es una hazaña lograr las condiciones correctas en su lugar:
write()
debe hacerse por un builtin (no por un comando externo), debe llenar el buffer de la tubería (el lector en el otro El final debe ser mucho más lento o no leer desde la tubería, pero aún estar vivo ), y el script debe usar trampas o la ventana del terminal debe ser redimensionada.Y debido a los diversos artefactos de implementación, esto solo afecta a
write()
s interrumpidos , noread()
s oopen()
s (como, por ejemplo, el bloqueoopen()
de una tubería con nombre / fifo).[1] una forma de esto ya se informó hace algún tiempo.
fuente