¿Cómo no hacer nada para siempre de forma elegante?

¿Cómo no hacer nada para siempre de forma elegante?

Tengo un programa que produce información útil stdoutpero 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 programalgo 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 yesrealmente escribe en la salida estándar. catsaldrá cuando su entrada estándar esté cerrada (o lo que sea que redirija a ella estará hecho). Creo sleep 1000000000dque podría funcionar, pero tailclaramente es mejor. Mi caja Debian tiene un tailfcomando que acorta ligeramente.

Tomando un rumbo diferente, ¿qué tal si ejecutamos el programa en screen?

Respuesta2

sleep infinityes la solución más clara que conozco.

Puedes usar infinityporque sleepacepta 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-1es 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 pausellamada 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 waitpida 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) .

información relacionada