Tengo un programa que produce información útil sobre stdout
pero también lee desde stdin
. Quiero redirigir su salida estándar a un archivo sin proporcionar nada en la entrada estándar. Hasta ahora todo bien:puedo hacer:
program > output
y no hagas nada en el tty.
Sin embargo, el problema es que quiero hacer esto en segundo plano. Si lo hago:
program > output &
el programa se suspenderá ("suspendido (entrada tty)").
Si lo hago:
program < /dev/null > output &
el programa termina inmediatamente porque llega a EOF.
Parece que lo que necesito es conectarme a program
algo que no hace nada por un tiempo indefinido y no lee stdin
. Los siguientes enfoques funcionan:
while true; do sleep 100; done | program > output &
mkfifo fifo && cat fifo | program > output &
tail -f /dev/null | program > output &
Sin embargo, todo esto es muy feo. Hay tiene ser una forma elegante, utilizando las utilidades estándar de Unix, de “no hacer nada, indefinidamente” (parafraseando a man true
). ¿Cómo podría lograr esto? (Mi criterio principal para la elegancia aquí:sin archivos temporales, sin esperas ocupadas o despertares periódicos, sin utilidades exóticas, lo más breve posible).
Respuesta aceptada:
En shells que los admitan (ksh, zsh, bash4), puede iniciar program
como un co-proceso.
ksh
:program > output |&
zsh
,bash
:coproc program > output
Eso inicia program
en segundo plano con su entrada redirigida desde un pipe
. El otro extremo del tubo está abierto al caparazón.
Tres beneficios de ese enfoque
- sin proceso adicional
- puede salir del script cuando
program
muere (usewait
esperarlo) program
terminará (obtenereof
en su stdin si el shell sale).