Ver "tubería rota" en esta situación es raro, pero normal.
Cuando ejecuta type rvm | head -1, bash se ejecuta type rvmen un proceso, head -1en otro. 1 El stdout de typeestá conectado al extremo de "escritura" de una tubería , el stdin de headal extremo de "lectura". Ambos procesos se ejecutan al mismo tiempo.
El head -1proceso lee los datos de la entrada estándar (generalmente en fragmentos de 8 kB), imprime una sola línea (según la -1opción) y sale, haciendo que se cierre el extremo "leído" de la tubería. Dado que la rvmfunción es bastante larga (alrededor de 11 kB después de ser analizada y reconstruida por bash), esto significa que las headsalidas typeaún tienen unos pocos kB de datos para escribir.
En este punto, dado que typeestá 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, typeobtiene 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 typees un comando incorporado de bash).
Esto parece ser más común en sistemas con múltiples CPU, ya que el typeproceso 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 typeincorporado (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 rvminstalación de ninguna manera.
lsmediohead -1de 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 +1en su tubería, de esta manera:El
+1le dicetailque imprima la primera línea de entrada y todo lo que sigue. La salida será exactamente la misma que sitail -n +1no 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 | headrinde 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=1Ma 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. , perodddebería ser el programa más eficiente para manejar tales cosas.El
write error: Broken pipemensaje 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 laSIGPIPEseñal está configurada para ser ignorada por el proceso actual o el proceso principal. Si fue el proceso padre el que se configuróSIGPIPEpara ser ignorado, no es posible que el proceso hijo lo deshaga nuevamente en un shell no interactivo.Sin embargo, es posible matar
type rvmcuandohead -1termina utilizando subcapas explícitas. De esta forma podemos hacer un fondotype rvm, enviartypepida lahead -1subshell y luego implementar una trampaEXITallí para matartype rvmexplícitamente.fuente
typeobtiene 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 (typeaquí) reaccione a la escritura fallida (debido a una tubería cerrada), ¿verdad?