Tengo un programa que produce información útil stdout
pero también lee 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 quedará suspendido ("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. AllátieneEs una forma elegante, utilizando utilidades estándar de Unix, de "no hacer nada, indefinidamente" (parafraseando man true
). ¿Cómo podría lograr esto? (Mi principal criterio de elegancia aquí: sin archivos temporales; sin esperas ocupadas ni despertares periódicos; sin utilidades exóticas; lo más breve posible).
Respuesta1
No creo que vayas a ser más elegante que el
tail -f /dev/null
que ya sugirió (suponiendo que esto use inotify internamente, no debería haber encuestas ni activaciones, por lo que, aparte de tener un aspecto extraño, debería ser suficiente).
Necesita una utilidad que se ejecute indefinidamente, que mantenga abierta su salida estándar, pero que en realidad no escriba nada en la salida estándar y que no salga cuando se cierre su entrada estándar. Algo así como yes
realmente escribe en la salida estándar. cat
saldrá cuando su entrada estándar esté cerrada (o lo que sea que redirija a ella estará hecho). Creo sleep 1000000000d
que podría funcionar, pero tail
claramente es mejor. Mi caja Debian tiene un tailf
comando que acorta ligeramente.
Tomando un rumbo diferente, ¿qué tal si ejecutamos el programa en screen
?
Respuesta2
sleep infinity
es la solución más clara que conozco.
Puedes usar infinity
porque sleep
acepta un número de punto flotante.*, que puede serdecimal,hexadecimal,infinidad, oYaya, de acuerdo a man strtod
.
* Esto no forma parte del estándar POSIX, por lo que no es tan portátil como tail -f /dev/null
. Sin embargo, es compatible con GNU coreutils (Linux) y BSD (usado en Mac) (aparentemente no es compatible con versiones más recientes de Mac; consulte los comentarios).
Respuesta3
sleep 2147483647 | program > output &
Sí, 2^31-1
es un número finito y no se ejecutará.para siempre, pero te daré $1000 cuando finalmente se acabe el tiempo de sueño. (Pista: uno de nosotros estará muerto para entonces).
- sin archivos temporales; controlar.
- sin largas esperas ni despertares periódicos; controlar
- sin utilidades exóticas; controlar.
- tan corto como sea posible. Vale, podría ser más corto.
Respuesta4
Puedes crear un binario que haga precisamente eso con:
$ echo 'main(){pause();}'| gcc -Wno-all -xc - -o pause
Encuentro esto elegante porque la pause
llamada al sistema es literalmente la única llamada al sistema cuyo único propósito es no hacer nada para siempre (o hasta que una señal mate el proceso) sin estar ocupado esperando, hacerlo como un efecto secundario de otra cosa o sin avisar al proceso principal (los padres pueden elegantemente y sin bloquear waitpid
a sus hijos para que se les detenga la señal, y muchos (sobre todo los shells) lo hacen, mientras que es bastante más difícil esperar a que un niño sea bloqueado en una llamada al sistema sin señal) .