Schreiben an stdin des Hintergrundprozesses

25

Ich bin auf einer Ubuntu 10.04 Box und habe einen Server im Hintergrund (myserver &) über ssh gestartet. Es läuft einwandfrei, aber ich brauche eine Möglichkeit, die Standardeinstellungen des Servers zu ermitteln, da die einzige Möglichkeit zur Steuerung des Servers über diese Methode besteht.

Gibt es eine Möglichkeit, die Standardeinstellung eines bereits laufenden Prozesses zu ermitteln, damit ich darauf schreiben kann (und hoffentlich die Standardeinstellung lesen kann)? Wenn ich das jetzt machen würde, würde ich es natürlich mit einem FIFO beginnen, das zu stdin umleitet, aber dafür ist es jetzt leider etwas spät.

Irgendwelche Ideen?

Tajmorton
quelle
Könnten Sie es nicht einfach wieder in den Vordergrund bringen? ('jobs' listet Ihren aktuellen Hintergrundprozess auf, 'fg $ X' bringt den Job zurück in den Vordergrund, Strg + B pausiert den Job und bringt Sie zu Ihrer Shell zurück, während 'bg' den pausierten Prozess in fortsetzt Hintergrund)
symcbean

Antworten:

10

Sie können versuchen, in das Verzeichnis / proc pid zu schreiben. Angenommen, die pid Ihrer Daemons ist 2000, versuchen Sie, an / proc / 2000 / fd / 0 zu schreiben

katriel
quelle
Danke ... das habe ich gleich gefunden, nachdem ich das gepostet habe (nach einem Tag des Schauens - typisch). Das scheint zu funktionieren (soweit Daten tatsächlich an das Programm gesendet werden). Leider akzeptiert das Programm die Befehle nicht. Ich habe getestet, wie der Server auf meinem lokalen Computer ausgeführt wird, und tatsächlich werden die Daten angezeigt, aber das Programm erkennt die Befehle nicht. Ich muss manuell die Eingabetaste auf dem Server-Terminal drücken, und dann wird nur der nicht erkannte Befehl angezeigt. Vielleicht etwas Java-Verrücktheit? Ich stecke fest ...
Tajmorton
1
Wie wäre es mit echo -e "something \ n"> / proc / 2000 / fd / 0?
Katriel
Tatsächlich ist dies nicht immer der Fall, da / proc / <pid> / fd / 0 auf mindestens einigen Systemen auf / dev / pts <some number> verweist ...
bk138
In der ersten Antwort auf serverfault.com/questions/178457/… wird darauf hingewiesen , dass dieser Ansatz nicht funktioniert.
barrycarter
2
Das funktioniert eigentlich nicht. Shell normalerweise (wenn keine Rohre oder Umleitungen verwenden) startet einen Befehl mit Datei - Deskriptoren 0durch 2Satz auf die gleiche Datei, die in der Regel ist ein virtuelles Terminal (so etwas wie /dev/pty/...). Der Befehl liest dann von FD 0und schreibt an FD 1und 2kommuniziert mit dem virtuellen Terminal (z. B. über SSH oder direkt mit Ihrem Terminalemulator). Wenn ein anderer Prozess auf diese Datei zugreift (z. B. durch /proc), geschieht genau das Gleiche, dh das Schreiben in diese Datei schreibt in das Terminal und nicht in den Befehl.
Feuermurmel
29

Sie könnten Ihren Server mit einer Named Pipe (Fifo) als Eingabe starten:

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

Dies cat > /tmp/srv-input &ist wichtig, um zu vermeiden, dass Ihr Server eine EOF empfängt. Bei mindestens einem Prozess muss das FIFO schriftlich geöffnet sein, damit Ihr Server keine EOF erhält. Die PID dieses Befehls wird in der /tmp/srv-input-cat-pidDatei für den letzten Kill gespeichert.

In Ihrem Fall, in dem Sie Ihren Server bereits gestartet haben, müssen Sie einen Debugger verwenden gdb, um eine Verbindung zu Ihrem Prozess stdinherzustellen und ihn an das FIFO umzuleiten:

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

Und dann tun Sie etwas wie unten, um Eingaben an Ihren Server zu senden (in einem anderen Terminalfenster, falls erforderlich):

echo "command" > /tmp/srv-input

Um eine EOF an Ihren Server zu senden, müssen Sie den cat > /tmp/srv-inputProzess beenden, in dem die PID gespeichert wurde /tmp/srv-input-cat-pid file.

Im Falle von GDB beenden Sie einfach GDB und EOF wird gesendet.

jfg956
quelle
1
Dies ist ein viel portablerer Ansatz als der von @katriel, da / proc / 2000 / fd / 0 nicht auf allen Systemen verfügbar ist.
Prior99,
Der Trick mit dem "cat> / tmp / srv-input &" hat mir Kopfschmerzen erspart. Vielen Dank!
Prior99,
Was ist mkfifo /tmp/srv-input; tail -f /tmp/srv-input | myserver &? Damit
bleibt auch
@ bk138: es sieht für mich so aus, als sollte der schwanz funktionieren, aber es gibt nur einen weg, um sicher zu wissen: test.
jfg956
tailfunktioniert nicht, fügt dies jedoch hinzu, um den Job zu beenden: cat /tmp/srv-input | myserver; kill -9 cat / tmp / srv-input-cat-pid` && rm / tmp / srv-input-cat * `
Thiago Macedo
4

Wie oben, aber "Katze" hat bei mir nicht funktioniert. Die Datei wurde EOF und endete nach dem Senden eines Befehls.

Das hat bei mir funktioniert:

#!/bin/bash

mkfifo /tmp/srv-input
tail -f /tmp/srv-input | myserver &
Tamir
quelle