Wie hänge ich ein Terminal an einen getrennten Prozess an?

99

Ich habe einen Prozess von meinem Terminal getrennt:

$ process &

Das Terminal ist jetzt schon lange geschlossen, processläuft aber noch, und ich möchte einige Befehle an die Standardeingabe dieses Prozesses senden. Ist das möglich?

Rogach
quelle

Antworten:

112

Ja ist es. Erstellen Sie zunächst ein Rohr: mkfifo /tmp/fifo. Verwenden Sie gdb, um an den Prozess anzuhängen: gdb -p PID

Dann schließen stdin: call close (0); und öffne es wieder:call open ("/tmp/fifo", 0600)

Zum Schluss schreibe weg (von einem anderen Terminal, da gdb wahrscheinlich hängen bleibt):

echo blah > /tmp/fifo

Ansgar Esztermann
quelle
6
Sehr beeindruckend!
Samuel Edwin Ward
1
Kann ich etwas Ähnliches tun, um den Prozess stdout in eine Datei umzuleiten?
Rustyx
@rustyx: Ungeprüfte, aber dies sollte funktionieren: eine Datei , anstatt ein Rohr erstellen, touch /tmp/thefile. Stdout ist 1, also call close (1); Verwenden Sie auch die richtigen Berechtigungen für das Schreiben: call open ("/tmp/thefile", 0400). Das echo…wird natürlich nicht benötigt.
Ansgar Esztermann
Das ist toll! Ich verwende dies, um "y" oder "n" Antworten auf bestimmte Prozesse zu senden, die vollständig getrennt wurden. Der getrennte Prozess hat seine Standardausgabe in einem separaten Fenster. Wenn ich diesen Trick mache, kann ich jedoch sehen, dass er das 'y' oder 'n' nicht "empfängt", sobald ich ihn wiedergebe, ich muss gdb beenden und ihn ablösen und dann empfängt er alle Echos entsprechend Gibt es eine Möglichkeit, dies durchzuführen, ohne GDB beenden zu müssen, bevor der Prozess die Eingabe vom FIFO empfängt?
krb686
leider scheint es nur aufgehängt zu sein call open("/tmp/fifo", 0600). Jede Hilfe wäre sehr dankbar
Bogenschütze
27

Wenn das ursprüngliche Terminal nicht mehr erreichbar ist ...

reptyrVielleicht ist es das, was Sie wollen, siehe https://serverfault.com/a/284795/187998

Zitat von dort:

Schauen Sie sich reptyr an , das macht genau das. Die Github-Seite enthält alle Informationen.

reptyr - Ein Tool zum "erneuten Kopieren" von Programmen.

reptyr ist ein Dienstprogramm zum Übernehmen eines vorhandenen laufenden Programms und zum Anhängen an ein neues Terminal. Hat einen lang laufenden Prozess über ssh gestartet, muss ihn aber verlassen und möchte ihn nicht unterbrechen? Starten Sie einfach einen Bildschirm, greifen Sie ihn mit reptyr, beenden Sie die ssh-Sitzung und fahren Sie nach Hause.

VERWENDUNGSZWECK

reptyr PID

"reptyr PID" erfasst den Prozess mit der ID PID und hängt ihn an Ihr aktuelles Terminal an.

Nach dem Anhängen übernimmt der Prozess die Eingabe von und schreibt die Ausgabe in das neue Terminal, einschließlich ^ C und ^ Z. (Leider müssen Sie im Hintergrund immer noch "bg" oder "fg" im alten Terminal ausführen. Dies lässt sich wahrscheinlich nicht auf vernünftige Weise beheben, ohne Ihre Shell zu patchen.)

NiKiZe
quelle
12

Ich bin mir ziemlich sicher, dass du es nicht kannst.

Überprüfen Sie mit ps x. Wenn ein Prozess eine hat ?als Steuerung tty , können Sie nicht eingegeben mehr an ihn schicken.

9942 ?        S      0:00 tail -F /var/log/messages
9947 pts/1    S      0:00 tail -F /var/log/messages

In diesem Beispiel können Sie Eingaben senden, 9947um etwas zu tun echo "test" > /dev/pts/1. Der andere Prozess ( 9942) ist nicht erreichbar.

Das nächste Mal könnten Sie screen oder tmux verwenden , um diese Situation zu vermeiden.

andcoz
quelle
5
Oder dtachwenn Sie kein Ganzes brauchen screen.
Manatwork
4
Es gibt keine Möglichkeit , in den Standards (POSIX, SUS), aber auf viele ( die meisten?) -Systeme es ist möglich , die Mechanismen , die Verwendung Debuggers. Siehe Ansgars Antwort . Mit können rootSie dies sogar für die Prozesse anderer Benutzer tun.
dmckee
3
Wenn Sie dies tun, echo "test" > /dev/pts/1werden keine Eingaben an den Prozess gesendet 9947- es wird das Wort "test" auf dem Terminal dieses Prozesses ausgegeben.
Psmears
6

EDIT : Wie Stephane Gimenez sagte, ist es nicht so einfach. Sie können nur auf einem anderen Terminal drucken.

Sie können versuchen, mit / proc in diesen Prozess zu schreiben . Es sollte sich in / proc / pid / fd / 0 befinden , also einfach:

echo "hello" > /proc/PID/fd/0

Sollte es tun. Ich habe es nicht ausprobiert, aber es sollte funktionieren, solange dieser Prozess noch einen gültigen stdin- Dateideskriptor hat. Sie können dies mit ls -lon / proc / pid / fd / überprüfen .

  • Wenn es sich um einen Link zu / dev / null handelt, ist er geschlossen
  • Wenn es ein Link zu / dev / pts / X oder ein Socket ist => ist es offen

Weitere Informationen zum Ausführen von Prozessen finden Sie unter nohup .

Coren
quelle
2
Es ist nicht so einfach. Beispiel: Wenn stdin mit einem Terminal verbunden ist, echodruckt etwas auf dem Terminalgerät nur das, was Sie auf dem Terminal geschrieben haben. Es wird nicht an den Prozess übertragen.
Stéphane Gimenez
5

Wenn Sie die Befehlszeile mit &beenden, wird der Prozess nicht vollständig getrennt, sondern nur im Hintergrund ausgeführt. (Mit können zshSie &!es tatsächlich lösen, sonst müssen Sie disownes später tun ).

Wenn ein Prozess im Hintergrund ausgeführt wird, erhält er keine Eingaben mehr von seinem steuernden Terminal. Aber Sie können es mit zurück in den Vordergrund schicken fgund dann liest es die Eingabe erneut.

Ansonsten ist es nicht möglich, von außen seine filedescriptors zu ändern (einschließlich stdin) oder einen verlorenen kontrollierende Terminal wieder zu befestigen ... es sei denn , Sie Debugging - Tools verwenden (siehe Ansgar Antwort oder einen Blick auf dem rettyBefehl).

Stéphane Gimenez
quelle
Und es gibt eine verwandte Frage hier: unix.stackexchange.com/q/17648/9426
Stéphane Gimenez
@Rogach gab an "Das Terminal ist jetzt lange geschlossen".
Andcoz
1
@andcoz: Ja, aber er hat Glück gehabt, dass das Programm nicht SIGHUPED wurde. Ich schlug eine sicherere Methode vor.
Stéphane Gimenez
hier, verleugne funktioniert nur wirklich , wenn ich zum ersten Mal stdout umleiten wie mit >>/dev/stderrsonst , wenn ich das Terminal schließen, wird die „verleugnet“ Prozess beenden .. ich wirklich noch nie so tho verstanden ..
Wassermann Strom