Ver "tubería rota" en esta situación es raro, pero normal.
Cuando ejecuta type rvm | head -1
, bash se ejecuta type rvm
en un proceso, head -1
en otro. 1 El stdout de type
está conectado al extremo de "escritura" de una tubería , el stdin de head
al extremo de "lectura". Ambos procesos se ejecutan al mismo tiempo.
El head -1
proceso lee los datos de la entrada estándar (generalmente en fragmentos de 8 kB), imprime una sola línea (según la -1
opción) y sale, haciendo que se cierre el extremo "leído" de la tubería. Dado que la rvm
función es bastante larga (alrededor de 11 kB después de ser analizada y reconstruida por bash), esto significa que las head
salidas type
aún tienen unos pocos kB de datos para escribir.
En este punto, dado que type
está intentando escribir en una tubería cuyo otro extremo se ha cerrado (una tubería rota ), la función write () que solicitó devolverá un error EPIPE, traducido como "tubería rota". Además de este error, el núcleo también envía la señal SIGPIPE a type
, que por defecto mata el proceso de inmediato.
(La señal es muy útil en shells interactivos, ya que la mayoría de los usuarios no quieren que el primer proceso continúe ejecutándose e intenten escribir en ninguna parte. Mientras tanto, los servicios no interactivos ignoran SIGPIPE; no sería bueno para un demonio de larga ejecución). morir en un error tan simple, por lo que encuentran el código de error muy útil).
Sin embargo, la entrega de la señal no es 100% inmediata, y puede haber casos en los que write () devuelve EPIPE y el proceso continúa ejecutándose por un corto tiempo antes de recibir la señal. En este caso, type
obtiene suficiente tiempo para notar la escritura fallida, traducir el código de error e incluso imprimir un mensaje de error en stderr antes de que SIGPIPE lo elimine. (El mensaje de error dice "-bash: type:" ya que type
es un comando incorporado de bash).
Esto parece ser más común en sistemas con múltiples CPU, ya que el type
proceso y el código de entrega de señal del núcleo pueden ejecutarse en diferentes núcleos, literalmente al mismo tiempo.
Sería posible eliminar este mensaje parcheando el type
incorporado (en el código fuente de bash) para salir inmediatamente cuando recibe un EPIPE de la función write ().
Sin embargo, no hay nada de qué preocuparse, y no está relacionado con su rvm
instalación de ninguna manera.
ls
mediohead -1
de años, y hoy estoy recibiendo un mensaje tubería rota.Puede arreglar una tubería rota a expensas de otro proceso insertando
tail -n +1
en su tubería, de esta manera:El
+1
le dicetail
que imprima la primera línea de entrada y todo lo que sigue. La salida será exactamente la misma que sitail -n +1
no estuviera allí, pero el programa es lo suficientemente inteligente como para verificar la salida estándar y cierra la tubería limpiamente. No más tuberías rotas .fuente
find /var/lib/mysql -xdev -type f -daystart -mmin +5 -print0 | xargs -0 ls -ldt | tail -n +1 | head
rinde de manera confiablexargs: ls: terminated by signal 13
. Como sabemos, el problema es el agotamiento de la entrada y en realidad solo hay un comando que se ocupa del almacenamiento en búfer: dd. Agregar| dd obs=1M
a la tubería corrige el SIGPIPE para mi caso de uso.type rvm | (head -1 ; dd of=/dev/null)
Esto, por supuesto, es similar a otras sugerencias ya que está causando que se procesen todas las entradas. , perodd
debería ser el programa más eficiente para manejar tales cosas.El
write error: Broken pipe
mensaje se refiere a un proceso de escritura que intenta escribir en una tubería sin lectores en el extremo de lectura de esa tubería y la circunstancia especial de que laSIGPIPE
señal está configurada para ser ignorada por el proceso actual o el proceso principal. Si fue el proceso padre el que se configuróSIGPIPE
para ser ignorado, no es posible que el proceso hijo lo deshaga nuevamente en un shell no interactivo.Sin embargo, es posible matar
type rvm
cuandohead -1
termina utilizando subcapas explícitas. De esta forma podemos hacer un fondotype rvm
, enviartypepid
a lahead -1
subshell y luego implementar una trampaEXIT
allí para matartype rvm
explícitamente.fuente
type
obtiene el tiempo suficiente para notar la escritura fallida, traduce el código de error e incluso imprime un mensaje de error en stderr antes de ser asesinado por SIGPIPE . Creo que su solución no impide que el proceso del productor (type
aquí) reaccione a la escritura fallida (debido a una tubería cerrada), ¿verdad?