Setzen Sie einen Prozess gestartet mit! im Hintergrund

8

Wenn ich das von der Shell aus mache:

$ sleep 100

Ich kann es in den Hintergrund treten lassen, indem ich:

^Z
$ bg

Und dann benutze meine Shell weiter. Sie können den gleichen Effekt erzielen, indem Sie &am Ende des Befehls ein hinzufügen , aber das vergesse ich oft.

In Vim mache ich oft:

:!sleep 100

Und auch hier vergesse ich oft, das hinzuzufügen &. Kann ich diesen Prozess in den Hintergrund stellen und Vim wie in der Shell weiter verwenden?

Martin Tournoij
quelle
1
Um ein erneutes Vergessen zu vermeiden, können Sie Vim &jedes Mal zum Anhängen auffordern : :nnoremap :! :!&<Left>... Aber manchmal möchten Sie das natürlich nicht &und müssen <Del> drücken, um es zu entfernen.
Joeytwiddle
@joeytwiddle Das ist eine gute Idee und klingt wie etwas, das Sie als Antwort schreiben könnten, anstatt nur einen Kommentar :-)
Martin Tournoij

Antworten:

5

Da <C-z>wird Vim selbst angehalten, nicht nur der gestartete Shell-Befehl, der nicht funktioniert.

Was ich tun würde, ist, den lang laufenden Befehl mit abzubrechen <C-c>und dann denselben Befehl im Hintergrund über neu zu starten

:!! &

(Der :!!Befehl ist praktisch, um den vorherigen externen Befehl hier abzurufen. Sie können auch den Ex-Befehlsverlauf über verwenden <Up>.)

Ingo Karkat
quelle
1
Dies ist genau der Workflow, den ich verbessern möchte. Das Problem ist, dass Sie alles schließen müssen, was Sie begonnen haben ...
Martin Tournoij
1

Sie können den Befehl in ein Shell-Skript einfügen, das sich selbst als Hintergrund verwendet. Der Inhalt könnte zum Beispiel sein:

#!/bin/sh
sleep 100 &
Jon Carter
quelle
3
Was nicht viel nützen würde, wenn der Befehl bereits gestartet wurde.
Muru
Ich meine, man könnte das Shell-Skript anstelle des langsamen Befehls ausführen. Wenn Sie den Hintergrund selbst haben, müssen Sie nicht mehr daran denken, ihn zur Laufzeit auszuführen. Ich glaube, ich verstehe den Anwendungsfall nicht sehr gut. Wenn es der gleiche Befehl ist, den ich immer wieder im Hintergrund vergesse, würde ich das Shell-Skript verwenden. Wenn dies mit beliebigen Befehlen geschieht, würde ich es mir zur Gewohnheit machen, zu einer tatsächlichen Shell zu wechseln, um dies zu tun.
Jon Carter
Ich verwende tmuxstandardmäßig, aber das Problem ist, dass meine Vim-Sitzung (mit geöffneten Dateien und dergleichen) immer noch nutzlos ist. Ich könnte in einen anderen Bereich wechseln und dort mein Skript ausführen, aber das sind viel mehr Aktionen als :!gitk %zum Beispiel ... Die Sache mit der Verwendung von Skripten ist, dass ich viele dieser Skripte für jeden möglichen Befehl vorab erstellen müsste. Vielleicht ist es keine schlechte Idee für einige der am häufigsten verwendeten Befehle (wie gitk& mupdf).
Martin Tournoij
1

Normalerweise haben Sie beim Starten eines Prozesses nur die Möglichkeit, ihn zu beenden ( Ctrl+ c) oder anzuhalten ( Ctrl+ z, aber einschließlich des übergeordneten Prozesses).

Je nach Prozesstyp und Betriebssystem können Sie jedoch einige Tricks ausprobieren:

  • Senden SIGTSTPoder SIGSTOPstoppt den Prozess (dasselbe Signal, das von Ctrl+ gesendet wurde z) und SIGCONTsetzt den Prozess fort (setzt ihn fort). Das Testen mit sleepfunktioniert nicht, daher müssen Sie es mit einer bestimmten Software testen, wie es mit den Signalen umgeht. Z.B

    killall -SIGSTOP sleep
    killall -SIGTSTP sleep
    kill -SIGTSTP PID
    

    SIGSTOP stop Prozessstopp (kann nicht abgefangen oder ignoriert werden)

    SIGTSTP-Stoppprozess-Stoppsignal, das von der Tastatur generiert wird

  • Senden SIGHUPan den Prozess. Standardmäßig beendet dieses Signal den Prozess. Wenn der Prozess jedoch das SIGHUP-Signal implementiert, sollte es sich von der Steuerung von tty lösen und im Hintergrund mit einer neuen Prozess-ID erneut ausgeführt werden (normalerweise wird es bei Dämonen verwendet). Leider gehen viele Anwendungen nicht richtig damit um und sterben einfach (einschließlich sleep). Z.B

    killall -SIGHUP sleep
    

    SIGHUP Prozess-Terminal-Line-Hangup beenden

  • Andere Lösungen könnten Tools wie retty(erneutes Anschließen an ein Pseudo-tty), detach( Trennen eines Prozesses vom Terminal), nohup( Trennen des Prozesses vom Terminal ) oder gdb(Anhängen an einen vorhandenen Prozess -pund Schließen der Dateideskriptoren wie tty, ähnliches Beispiel) verwenden ).

Weitere Informationen finden Sie unter: Job Control (Unix) - Implementierung bei Wikipedia.

Siehe auch: man killoder man sigaction.

Kenorb
quelle
Es ist seltsam, dass dies für Sie funktioniert - es sollte nicht. STOP / CONT sollte nur pausieren und den Vorgang fortsetzen, sonst nichts. Hier funktioniert es weder in Console Vim noch in GVIM.
Derobert
1

Hinweis : Diese Antwort scheint nur mit den Shells tcshund zu funktionieren fish. Ich habe auch versucht bash, dash, mksh, und zsh, und es nicht dort arbeiten; Ich bin mir nicht sicher , warum, denn wenn wir die gleichen Aktionen aus diesen Schalen ohne Vim tun, es tut wie erwartet ... ( :!Befehle obwohl die Shell ausgeführt werden).

Ich benutze zufällig tcsh, also funktioniert es für mich ...

Sie können verwenden :set shell=/bin/tcsh, um Ihre Shell festzulegen; Dies ist jedoch global. Verwenden Sie es also nur, wenn Sie der Meinung sind, dass dies eine sehr wichtige Funktion ist :-)


^ZSenden Sie ein SIGTSTPSignal, Sie können dieses Signal mit senden killund dann verwenden SIGCONT, um den Vorgang fortzusetzen (fortzusetzen). Dadurch wird der Prozess von Vim getrennt.

Da es schwierig ist, dies zu zeigen sleep(woher wissen Sie, dass die Ausführung fortgesetzt wurde?), Werde ich gitkals Beispiel verwenden (aber jedes GUI-Programm wird dies tun):

Zum Beispiel in Vim:

:!gitk %

Und dann in einem anderen Terminal:

$ ps ax | grep gitk
30105 pts/10   S+     0:00 -bin/tcsh -c gitk
30108 pts/10   Sl+    0:00 wish /sbin/gitk --

$ kill -TSTP 30108
$ kill -CONT 30108

Sie können natürlich auch verwenden killall, oder pkill; zum Beispiel:

$ killall -TSTP wish
$ killall -CONST wish

Sie müssen hierfür ein anderes Terminal öffnen, was nicht ideal ist, aber es ermöglicht Ihnen, sowohl Ihr Vim als auch Ihren externen Prozess weiter zu verwenden.

Martin Tournoij
quelle