Scrittura su stdin del processo in background


25

Sono su una casella Ubuntu 10.04 e ho avviato un server in background (myserver &) su ssh. Sta funzionando bene, ma ho bisogno di un modo per accedere allo stdin del server, poiché l'unico modo per controllare il server è attraverso questo metodo.

C'è un modo per arrivare allo stdin di un processo già in esecuzione in modo che io possa scrivergli (e spero di leggere il suo stdout)? Ovviamente, se l'avessi fatto adesso, lo inizierei con un FIFO che reindirizza a stdin, ma sfortunatamente è un po 'tardi per quello ora.

Qualche idea?


Non potresti riportarlo in primo piano? ('jobs' elencherà il tuo attuale processo in background, 'fg $ X' riporterà il lavoro in primo piano, ctrl + b metterà in pausa il lavoro e ti riporterà nella tua shell, mentre 'bg' continuerà il processo in pausa nella sfondo)
symcbean

Risposte:


10

Potresti provare a scrivere nella sua directory / proc pid. Supponiamo che il pid dei tuoi demoni sia 2000, prova a scrivere su / proc / 2000 / fd / 0


Grazie ... L'ho scoperto subito dopo aver pubblicato questo (dopo una giornata di ricerca - tipica). Sembra funzionare (per quanto riguarda effettivamente l'invio di dati al programma). Sfortunatamente, il programma non accetta i comandi. L'ho provato eseguendo il server sul mio computer locale e, sicuramente, vedo apparire i dati, ma il programma non riconosce i comandi. Devo premere manualmente Invio sul terminale del server, quindi dice solo un comando non riconosciuto. Forse qualche stranezza Java? Sono bloccato ...
Tajmorton,

1
che ne dici di echo -e "qualcosa \ n"> / proc / 2000 / fd / 0?
Katriel,

In realtà, questo non è sempre lo sworking come / proc / <pid> / fd / 0 punta a / dev / pts <un certo numero> su almeno alcuni sistemi ...
bk138

La prima risposta a serverfault.com/questions/178457/… osserva che questo approccio in realtà non funziona.
Barrycarter,

2
Questo in realtà non funziona. La shell normalmente (quando non si usano pipe o reindirizzamenti) avvia un comando con descrittori di file 0tramite 2lo stesso file, che normalmente è un terminale virtuale (qualcosa del genere /dev/pty/...). Il comando quindi legge da FD 0e scrive su FD 1e 2per comunicare con il terminale virtuale (ad es. Tramite SSH o direttamente con l'emulatore di terminale). Se qualsiasi altro processo accede a quel file (ad es. Tramite /proc), accade esattamente la stessa cosa, ovvero scrivere su di esso scrive sul terminale e non sul comando.
Feuermurmel,

29

È possibile avviare il server con una pipe denominata (fifo) come input:

mkfifo /tmp/srv-input
cat > /tmp/srv-input &
echo $! > /tmp/srv-input-cat-pid
cat /tmp/srv-input | myserver &

Il cat > /tmp/srv-input &è importante per evitare il server per ricevere un EOF. Almeno un processo deve avere il Fifo aperto per iscritto in modo che il tuo server non riceva un EOF. Il PID di questo comando viene salvato nel /tmp/srv-input-cat-pidfile per quest'ultima uccisione.

Nel tuo caso in cui hai già avviato il tuo server, devi utilizzare un debugger tale da gdbcollegarti al tuo processo per reindirizzarlo stdinal FIFO:

gdb -p PID
call close(0)
call open(0, "/tmp/srv-input", 0600)

E poi fai qualcosa come muggito per inviare input al tuo server (in un'altra finestra terminale se necessario):

echo "command" > /tmp/srv-input

Per inviare un EOF al tuo server, devi interrompere il cat > /tmp/srv-inputprocesso in cui il PID è stato salvato nel file /tmp/srv-input-cat-pid file.

Nel caso di GDB, basta uscire da GDB e verrà inviato EOF.


1
questo è un approccio molto più portatile di quello di @katriel in quanto / proc / 2000 / fd / 0 non è standard su tutti i sistemi.
Prior99

Il trucco con "cat> / tmp / srv-input &" mi ha fatto venire il mal di testa. Grazie!
Prior99

Che dire mkfifo /tmp/srv-input; tail -f /tmp/srv-input | myserver &? Questo manterrà aperto anche il tubo ...
bk138

@ bk138: mi sembra che la coda dovrebbe funzionare, ma c'è solo un modo per saperlo con certezza: prova.
jfg956,

tailnon funziona, ma è stato aggiunto per completare il lavoro: cat /tmp/srv-input | myserver; kill -9 cat / tmp / srv-input-cat-pid` && rm / tmp / srv-input-cat * `
Thiago Macedo

4

Come sopra, ma "gatto" non ha funzionato per me. Il file ha ottenuto EOF e si è concluso dopo aver inviato un comando.

Questo ha funzionato per me:

#!/bin/bash

mkfifo /tmp/srv-input
tail -f /tmp/srv-input | myserver &
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.