¿Cómo hago un script de shell que envía resultados a un proceso?

11

Actualmente estoy ejecutando un programa de consola del servidor en una pantalla porque necesito leerlo y ocasionalmente enviar comandos.

Me gustaría ejecutar la aplicación como un demonio en segundo plano (iniciar / detener con init).

Podía tail -finiciar sesión, pero eso no me permite enviar información al proceso.

¿Hay alguna forma de configurar esto para que pueda leer y enviar entradas, pero aún así tenerlo ejecutándose en segundo plano?

También me gustaría poder enviar información al demonio desde diferentes procesos (un script de shell que podría enviar un comando "Stop \ n", por ejemplo).

Bill K
fuente
Solo un comentario para cualquiera que vaya a leer esto: la respuesta aquí es fantástica. Si no conoce las tuberías con nombre, le recomiendo que al menos las pruebe. Utilizando esto, podría ejecutar Minecraft como un servicio e interactuar con la consola desde otros scripts escribiendo en la tubería con nombre, por lo que es posible escribir scripts para detener el servidor, enviar mensajes a los usuarios, etc. mientras aún analiza el registro de salida buscar líneas clave (como enviar mensajes de chat dirigidos a un usuario como mensajes de texto)
Bill K

Respuestas:

9

Leer desde una tubería, escribir en un archivo

Si desea que el daemon lea la entrada producida por algún proceso arbitrario, debe conectar ese proceso a una tubería. Aquí el proceso arbitrario es hacer eco de comandos, y se ejecutará en un contexto diferente. Por lo tanto, cree una tubería con nombre (a menudo llamada fifo en contextos unix).

mkfifo /var/run/daemon.fifo
</var/run/daemon.fifo /path/to/daemond --option >daemon.log

Y solo escribe comandos en la tubería:

echo 'FORWARD 10' >/var/run/daemon.fifo
echo 'LEFT 72' >/var/run/daemon.fifo

Sin embargo, es poco probable que funcione como tal: hay una buena posibilidad de que el demonio salga cuando vea un final de archivo en su entrada estándar, lo que ocurre tan pronto como finaliza el primer proceso que escribe en la tubería. Puedes usar tail -fpara evitar ese problema.

</var/run/daemon.fifo tail -c +1 -f | {
  echo $$ >/var/run/daemon.pid
  exec /path/to/daemond --option >daemon.log
}

Con algunas tailimplementaciones, puede ser mordido mediante almacenamiento en búfer: el tailproceso esperará hasta que haya acumulado suficientes bytes para emitir algo de salida. No creo que esto sea solucionable en la caja de herramientas POSIX; Si eso es un problema, utilice un programa trivial C o Perl o Python. Por lo que puedo decir, tailGNU coreutils (como se encuentra en Linux y en otros lugares) es seguro a este respecto.

Cuando detengas al demonio, echo >/var/run/daemon.fifomatará el tailproceso.


Inicio del programa dentro de la pantalla

En lugar de invocar el demonio directamente desde su administrador de servicio (¿realmente está usando solo SysV init, o algo adicional como scripts de envoltura o Upstart?), Invoque

screen -c daemon.screenrc -L -d -m -S daemon_name /path/to/daemond --option

Dado que el demonio no será un proceso secundario del administrador de servicios, debe asegurarse de enviar una señal al proceso correcto. Cómo hacerlo depende exactamente de cómo se inicia el demonio y por qué.

Es técnicamente posible adjuntar un proceso en ejecución a una terminal, pero existe el riesgo de que bloquee el programa, por lo que definitivamente está fuera de servicio para un sistema de producción.

La -Lopción hace que la pantalla escriba todo lo que aparece en su ventana en un archivo. El nombre del archivo se proporciona daemon.screenrccon la logfiledirectiva.

Gilles 'SO- deja de ser malvado'
fuente
En realidad, realmente me gustaría poder enviar mensajes a su stdin desde un script, tal vez esa es la pregunta que debería haber hecho. Actualmente solo estoy ejecutando el servidor desde un script y puedo escribirlo en un terminal, pero parece que debería estar ejecutándose como un servicio ...
Bill K
@ Bill: Ok, ya veo. Entonces, lo primero que me viene a la mente es una tubería con nombre.
Gilles 'SO- deja de ser malvado'
¡Creo que esto es exactamente lo que quiero @Gilles! Aunque necesito entenderlo mejor. Pasaré un tiempo clasificando las páginas del manual para resolverlo. Sinceramente, obtengo muy poco de eso (obtengo la mayor parte de lo que está haciendo y casi nada de cómo lo hizo), y pensé que tenía una especie de pista con estas cosas.) Mi teoría no era conectarme directamente al proceso, sino crear otro script que uniera su E / S a los demonios o / i para que pareciera que la consola original se está ejecutando, pero con la capacidad hacer el eco 'FORWARD 10' de otro script al mismo tiempo.
Bill K
Creo que tengo mucho de eso. Si lo descompongo ahora entiendo "mkfifo pipe" y "tail -f pipe | command> output", los probé y funcionan. Creo que la mayoría de las otras cosas que tenía eran trucos para que funcionara en una línea: ¿me estoy perdiendo algo crítico?
Bill K
@Bill: Puede escribir en la pantalla interna del terminal desde el exterior (usando el stuffcomando de pantalla ). Pero no necesita la sobrecarga (procesamiento, pero lo más importante cognitivo) de un terminal aquí, una tubería es casi suficiente (es suficiente con un pequeño proceso de retransmisión que ignora el final del archivo). Es posible que desee experimentar un poco con <fifo cato <fifo tail -f | caten un terminal y echo >fifo; echo >fifoen otro terminal; Creo que estarás bien.
Gilles 'SO- deja de ser malvado'