Come faccio a creare uno script shell che invia l'output a un processo


11

Attualmente sto eseguendo un programma console server in una schermata perché ho bisogno sia di leggerlo che di inviare occasionalmente comandi.

Vorrei eseguire l'app come demone in background (avviarla / fermandola con init).

Potrei tail -fil registro, ma ciò non mi consente di inviare input al processo.

Esiste un modo per configurarlo in modo che sia in grado di leggere e inviare input, ma che sia ancora in esecuzione in background?

Vorrei anche essere in grado di inviare input al demone da diversi processi (uno script shell che potrebbe inviare un comando "Stop \ n", per esempio).


Solo un commento a chiunque venga a leggere questo: la risposta qui è fantastica. Se non conosci le pipe nominate, ti consiglio vivamente di provarle. Usando questo ho potuto eseguire Minecraft come servizio e interagire con la console da altri script scrivendo nella pipa denominata - quindi diventa possibile scrivere script per arrestare il server, inviare messaggi agli utenti, ecc. Mentre analizzavo ancora il registro di output cercare le linee chiave (come l'invio di messaggi di chat indirizzati a un utente come messaggi di testo)
Bill K,

Risposte:


9

Leggi da una pipe, scrivi su un file

Se si desidera che il demone legga l'input prodotto da un processo arbitrario, è necessario connettere tale processo a una pipe. Qui il processo arbitrario sta facendo eco ai comandi e verrà eseguito in un contesto diverso. Quindi crea una pipe con nome (spesso chiamata un quindicesimo in contesti unix).

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

E basta scrivere i comandi nella pipe:

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

È improbabile che ciò funzioni come è comunque: c'è una buona probabilità che il demone esca quando vede la fine del file sul suo input standard, cosa che accade non appena termina il primo processo che scrive nella pipe. Puoi usarlo tail -fper evitare quel problema.

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

Con alcune tailimplementazioni, potresti essere morso dal buffering: il tailprocesso attenderà fino a quando non avrà accumulato abbastanza byte per emettere un output. Non penso che questo sia risolvibile nella casella degli strumenti POSIX; se questo è un problema, usa un banale programma C o Perl o Python. Per quanto ne so, taildai coreutils di GNU (come si trova su Linux e altrove) è sicuro su questo punto.

Quando interrompi il demone, echo >/var/run/daemon.fifoil tailprocesso verrà interrotto .


Avvio del programma all'interno della schermata

Invece di invocare il demone direttamente dal tuo gestore servizi (stai davvero usando solo SysV init o qualcosa di aggiuntivo come gli script wrapper o Upstart?), Invoca

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

Poiché il daemon non sarà un processo figlio del gestore servizi, è necessario assicurarsi di inviare un segnale al processo corretto. Come farlo dipende esattamente da come viene avviato il demone e da cosa.

È tecnicamente possibile collegare un processo in esecuzione a un terminale, ma c'è il rischio che si blocchi il programma, quindi questo è sicuramente fuori per un sistema di produzione.

L' -Lopzione fa scrivere allo schermo tutto ciò che appare nella sua finestra in un file. Il nome del file viene fornito daemon.screenrccon la logfiledirettiva.


In realtà, mi piacerebbe davvero poter inviare messaggi al suo stdin da uno script - forse questa è la domanda che avrei dovuto porre. Attualmente sto solo eseguendo il server da uno script e sono in grado di digitarlo in un terminale, ma sembra proprio che dovrebbe essere in esecuzione come servizio ...
Bill K,

@Bill: Ok, capisco. Quindi la prima cosa che mi viene in mente è una pipa chiamata.
Gilles 'SO- smetti di essere malvagio' il

Penso che sia esattamente quello che voglio @Gilles! Devo capirlo meglio però. Trascorrerò un po 'di tempo a cercare tra le pagine man per capirlo - onestamente ne ottengo molto poco (ottengo la maggior parte di ciò che stai facendo e quasi nessuno di come lo hai fatto - e pensavo di aver avuto un indizio con questa roba.) La mia teoria non era quella di connettersi direttamente al processo ma di creare ancora un altro script che unisse il suo I / O ai Deamon o / i per far sembrare che la console originale fosse in esecuzione, ma con l'abilità per fare l'eco 'FORWARD 10' da un altro script contemporaneamente.
Bill K,

Penso di averne molto. Se lo scompongo ora capisco "mkfifo pipe" e "tail -f pipe | command> output", li ho testati e funzionano. Penso che la maggior parte delle altre cose che hai avuto fossero trucchi per farlo funzionare su una linea - mi sto perdendo qualcosa di critico?
Bill K,

@Bill: è possibile scrivere sul terminale all'interno dello schermo dall'esterno (usando il stuffcomando dello schermo ). Ma non è necessario l'overhead (elaborazione, ma soprattutto cognitivo) di un terminale qui, una pipe è quasi sufficiente (è sufficiente con un piccolo processo di inoltro che ignora la fine del file). Potresti voler sperimentare un po 'con <fifo cato <fifo tail -f | catin un terminale e echo >fifo; echo >fifoin un altro terminale; Penso che starai bene.
Gilles 'SO- smetti di essere malvagio' il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.