Existe una regla general de almacenamiento en búfer seguida de la biblioteca de E / S estándar C ( stdio) que utilizan la mayoría de los programas Unix. Si la salida va a un terminal, se vacía al final de cada línea; de lo contrario, se vacía solo cuando el búfer (8K en mi sistema Linux / amd64; podría ser diferente en el suyo) está lleno.
Si todos sus utilidades estaban siguiendo la regla general, que se vería retrasada de salida en todos sus ejemplos ( cat|sed, cat|try cat|tr|sed). Pero hay una excepción: GNU catnunca amortigua su salida. No se usa stdioo cambia la stdiopolítica de almacenamiento en búfer predeterminada .
Puedo estar bastante seguro de que estás usando GNU caty no algún otro Unix catporque los demás no se comportarían de esta manera. Unix tradicional cattiene una -uopción para solicitar una salida sin búfer. GNU catignora la -uopción porque su salida siempre está sin búfer.
Entonces, siempre que tenga una tubería con un cata la izquierda, en el sistema GNU, el paso de datos a través de la tubería no se retrasará. El catni siquiera se va línea por línea - su terminal está haciendo eso. Mientras escribe la entrada para cat, su terminal está en modo "canónico", basado en líneas, con teclas de edición como retroceso y ctrl-U que le ofrecen la oportunidad de editar la línea que ha escrito antes de enviarla Enter.
En el cat|tr|sedejemplo, trsigue recibiendo datos cattan pronto como presiona Enter, pero trsigue la stdiopolítica predeterminada: su salida se dirige a una tubería, por lo que no se vacía después de cada línea. Escribe en la segunda tubería cuando el búfer está lleno o cuando se recibe un EOF, lo que ocurra primero.
sedtambién sigue la stdiopolítica predeterminada, pero su salida se dirige a un terminal, por lo que escribirá cada línea tan pronto como haya terminado. Esto tiene un efecto sobre cuánto debe escribir antes de que algo aparezca en el otro extremo de la tubería: si sedbloqueaba su salida, tendría que escribir el doble (para llenar trel búfer de salida y sed la salida de buffer).
GNU sedtiene la -uopción, por lo que si invierte el orden y lo usa cat|sed -u|tr, verá que la salida aparece instantáneamente nuevamente. (La sed -uopción puede estar disponible en otros lugares, pero no creo que sea una tradición antigua de Unix cat -u) Hasta donde puedo decir, no hay una opción equivalente para tr.
Hay una utilidad llamada stdbufque le permite alterar el modo de almacenamiento en búfer de cualquier comando que use los stdiovalores predeterminados. Es un poco frágil ya que utiliza LD_PRELOADpara lograr algo que la biblioteca C no fue diseñada para soportar, pero en este caso parece funcionar:
cat | stdbuf -o 0 tr '[:lower:]' '[:upper:]' | sed 'p'
catalmacenando en búfer hasta que se cierra la entrada estándar.