Prozesse im Hintergrund ohne "&"

24

Angenommen, Sie haben eine neue Anwendung unter Linux gestartet (z. B. einen Texteditor usw.), aber Sie haben vergessen, das "&" zu verwenden. Welche Befehle würden Sie verwenden, um diesen Prozess im Hintergrund auszuführen, ohne diese Anwendung zu schließen? Auf diese Weise können beide Prozesse geöffnet und separat ausgeführt werden (z. B. das Befehlszeilenterminal, mit dem Sie den Prozess erstellt haben, und der Prozess, z. B. ein Texteditor, werden weiterhin ausgeführt.

D0uble7
quelle
Technisch nicht, tmuxbietet aber vielleicht die gleiche Funktionalität wie in Ihrer Frage gewünscht.
MKC
1
Übersehen Sie nicht die einfache Alternative, wenn möglich eine andere Shell zu öffnen.
jpmc26

Antworten:

43

Im Terminalfenster würden Sie normalerweise Control+ Zeingeben, um den Prozess "anzuhalten" und ihn dann mit dem bgBefehl "im Hintergrund" zu "unterbrechen" .

zB mit einem Schlafbefehl

$ /bin/sleep 1000
^Z[1] + Stopped                  /bin/sleep 1000
$ bg
[1]     /bin/sleep 1000&
$ jobs
[1] +  Running                 /bin/sleep 1000
$ 

Wir können sehen, dass der Prozess ausgeführt wird und ich immer noch meine Befehlszeile habe.

Stephen Harris
quelle
5
Es könnte interessant sein, hinzuzufügen, dass der Prozess mit dem fgBefehl wieder in den Vordergrund gebracht werden kann , der die Job-ID ( 1in diesem Fall in Klammern angegeben ) als Parameter verwendet. Es ist nicht spezifisch für die Verwendung von bgund kann für Prozesse ausgeführt werden, die mit gestartet wurden &.
Aaron
14

Ctrl+ Zist der Weg, dies zu tun, aber nur der Vollständigkeit halber: Die Frage fragt nach "Befehl" und das wäre (von einem anderen Terminal aus):

kill -STOP pid_of_the_running_applications

und dann natürlich

bg

vom Anwendungsterminal.

Radovan Garabík
quelle
6
kil -STOP, und dann töten -CONT
Michel Billaud
10

In Bash:

Ctrl+ Zund dann bg.

Laufen Sie jetzt jobsund sehen Sie das Ergebnis.

Tomasz
quelle
2
@grooveplex Tomas antwortete zuerst, daher wäre es angemessener, unter Stephens Antwort zu erwähnen, dass es sich bei seiner Antwort im Grunde um die Antwort von Tomas handelt, die etwas detaillierter ist.
Anthon
2
Wir haben tatsächlich gleichzeitig geantwortet. Kein Wunder, dass wir beide dasselbe gesagt haben, da es die offensichtliche Antwort ist :-) Keiner von uns hat den anderen kopiert. Meine Antwort kam kurz nach Thomas ', weil ich die zusätzliche Zeit damit verbracht hatte, das Beispiel zu erstellen und zu formatieren.
Stephen Harris
1
Und meins sagt, es ist in Bash, also sind sie nicht gleich.
Tomasz
1
Heh, da ist ein möglicher Punkt. Die Shell muss die Job-Kontrolle haben. Einige der ersten Maschinen, an denen ich gearbeitet habe (SVr2-basiert), hatten das nicht /bin/shund das hätte auch nicht funktioniert :-)
Stephen Harris
1

Als vorbeugende Maßnahme für die Unannehmlichkeit, CTRL- drücken zu müssen z, könnten Sie ein Wrapper-Skript für Ihren Editor erstellen, auf das Ihr Editor im Hintergrund ausgeführt wird. Auf diese Weise müssen Sie sich nicht mehr daran erinnern, es explizit im Hintergrund zu starten:

    #!/bin/sh

    EDITOR="emacs" # or whatever

    if [ -z "${DISPLAY}" ]; then
      ${EDITOR} "$@"
    else
      ${EDITOR} "$@" &
    fi

Oben versuchen wir zunächst festzustellen, ob ein X-Server verfügbar ist, und führen dann den Editor im Hintergrund aus (andernfalls verwenden viele Unix-Editoren stattdessen Ihr Terminal und möchten den Editor in diesem Fall nicht als Hintergrundprozess ausführen). . Alle Argumente werden wörtlich ( "$@") an den Editor Ihrer Wahl übergeben, so wie Sie es für das Wrapper-Skript angegeben haben.

Was den Befehl anbelangt, den Sie vermissen ... Nach meinen grundlegenden Experimenten kann es für GUI-Programme, die kein Terminal beinhalten, so einfach sein, zuerst einen Prozess zu senden SIGSTOPund ihn dann SIGCONTin den Vordergrund zu stellen (mithilfe des killBefehls, wenn Sie ein Shell-Skript verwenden, um dies zu implementieren). . Sie müssten es natürlich in einem anderen Terminalfenster / -register ausführen, und die Schwierigkeit wäre, die PID, an die Sie Ihr Signal senden möchten, bequem und allgemein zu finden. Sie können die beiden Signale standardmäßig an alle Prozesse mit dem angegebenen Namen senden (standardmäßig an Ihren bevorzugten Editor und die Verwendung von PIDs als Argumente zulassen):

    #!/bin/sh

    EDITOR=emacs # whatever

    stop_cont_prog()
    {
      case "$1" in
        # begin with number is considered PID - this is not good 
        # enough to be taken seriously...
        [1-9]*) kill -SIGSTOP "$1"; kill -SIGCONT "$2";;
        *)      killall -SIGSTOP "$1"; killall -SIGCONT "$2";;
      esac
    }

    if [ -n "$1" ]; then
      for prog in "$@"; do stop_cont_prog "$1"; done
    else  
      stop_cont_prog "${EDITOR}"
    fi

Diese Methode gab mir meine Terminal-Tabs korrekt, nachdem ich (mehrere) emacsBefehle im Hintergrund ausgeführt hatte. Der im Terminal ausgeführte Emacs-Prozess wurde jedoch aufgrund von Problemen mit der Shell-Jobsteuerung oder den Terminaleinstellungen nicht ordnungsgemäß wiederhergestellt. Diese Methode würde also von einer gewissen Sophistifizierung profitieren.

Das SIGSTOPist genau das, was in den Vordergrund Prozess senden wird , wenn Sie die Taste (durch gemeinsamen Standardwert) CTRL- z. Siehe stty -aAusgabe

$ stty -a
speed 38400 baud; rows 50; columns 200; line = 0;
intr = ^C; [...] start = ^Q; stop = ^S; susp = ^Z; [...]
[...]

(Ausgabe abgekürzt) und sttyHandbuchseite:

   susp CHAR
          CHAR will send a terminal stop signal

Prozesse, die mit dem SIGSTOPSignal gestoppt wurden, können durch Senden neu gestartet werden SIGCONT. Normalerweise ist es die Shell-Job-Steuerungslogik, die SIGCONTdie anderen notwendigen Manipulationen fgund bgBefehle sendet und sich darum kümmert, die wir ignorieren.

FooF
quelle