Was ist der Zweck des eingebauten Bash-Befehls "suspend"?

22

Ich schrieb help suspendund bekam diese kurze Erklärung:

suspend: suspend [-f]
    Suspend shell execution.

    Suspend the execution of this shell until it receives a SIGCONT signal.
    Unless forced, login shells cannot be suspended.

    Options:
      -f    force the suspend, even if the shell is a login shell

    Exit Status:
    Returns success unless job control is not enabled or an error occurs.

So verstehe ich das: Ich suspendtippe und das Terminal friert ein, auch strg + c kann es nicht entfrosten. Aber wenn ich ein anderes Terminal öffne und nach der PID für das eingefrorene suche und kill -SIGCONT PID-NRein SIGCONT-Signal eingebe, wird es an das eingefrorene Terminal gesendet und aufgetaut, sodass es nicht mehr gefroren ist.

Aber was ist der eigentliche Zweck des Suspendierens eines Terminals? Welche Alltagsanwendungen sind typisch dafür? Was dachten die Leute, die es zu einer eingebauten Shell gemacht haben?

Hai
quelle
2
Vermeiden Sie es, externe Programme (kill) zum Anhalten auszuführen.
Ipor Sircer

Antworten:

23

Wenn Sie eine Shell von einer anderen Shell aus starten, können Sie die innere anhalten. Sagen Sie, wenn Sie verwenden suund für einen Moment zum normalen Benutzer zurückkehren möchten:

user$ su
Password: ...
root# do something
root# suspend
user$ do something as the ordinary user again
user$ fg
root# ...

(Wenn Sie das tun, vergessen Sie nicht die privilegierte Shell, die im Hintergrund geöffnet ist ...)

In ähnlicher Weise können Sie die Shell auch anhalten, wenn Sie von einem anderen Programm ( !z. B. dem Befehl in less) zu einer Shell wechseln. Aber ich würde nicht erwarten, dass viele andere Programme gut damit umgehen, wenn sie einen Unterprozess starten, der sich dann selbst aussetzt.

ilkkachu
quelle
1
Ich habe gerade versucht zu rennen vimund habe a ausgeführt :sh, um eine Unterschale zu erhalten (speziell eine zshUnterschale). Beim Laufen suspendbin ich in die Original- Shell geraten (die sowohl die Subshell als auch die Vim aufgehängt hat).
Kevin
1
@ Kevin, das zshscheint klüger zu sein als bash, ich habe versucht, sowohl vor lessals auch vor vi(Debians vim.tiny) zu fliehen : habe auch zshdie Eltern-App gestoppt, bashdas Ganze aufgehängt. bashIn den bashWerken though.
ilkkachu
1
mir war nicht bewusst, dass bei der eingabe von sudo su eine subshell gestartet wird. Wenn ich suspend in der Haupt-Shell eingetippt habe, friert die Shell einfach ein, aber wie Sie gezeigt haben, gehe ich automatisch zur Haupt-Shell zurück, wenn ich sie in der Sub-Shell übergebe.
Hai
25

Dies entspricht dem Drücken Ctrl+Zanderer Befehle.

Es setzt die Shell aus und gibt die Kontrolle an die übergeordnete Shell oder den übergeordneten Prozess zurück, falls vorhanden.

Beispiel:

zsh$ bash
bash-4.4$ cd /
bash-4.4$ suspend
zsh: suspended (signal)  bash
zsh$ fg
[1]  + continued  bash
bash-4.4$ pwd
/

Das Feature stammt von csh, der BSD-Shell (von der die Job-Kontrolle stammt) in den frühen 80ern .

In AT & T kshist es ein eingebauter Alias ​​für kill -s STOP $$( ja, ohne Anführungszeichen! )

In deinem Fall bashwurde wahrscheinlich der direkt vom Terminalemulator gestartet. Und Ihr Terminal-Emulator hat nicht damit gerechnet, dass der Prozess unterbrochen wird.

Das bashwar ein Sitzungsleiter. Wenn der Sitzungsleiter suspendiert ist und wir die Ansicht alter Zeitterminals vertreten, hat der Benutzer keine Möglichkeit, diese fortzusetzen.

bashbehebt dies, indem es ablehnt, suspendwenn es sich um eine Anmeldeshell handelt. In Ihrem Fall startet der Terminal-Emulator jedoch möglicherweise nicht bashim Anmeldemodus, sodass keine Sicherheitsvorkehrungen getroffen werden.

zshund mkshhaben Sie nicht das Problem, weil sie ein SIGTSTP(das auch gesendete Ctrl+Z) Signal wie csh anstelle von SIGSTOP(und an die Prozessgruppe des Aufrufers für mkshwie in csh und an die Hauptprozessgruppe der Shell für zsh, nicht den $$Prozess allein, senden ). SIGTSTPwird ignoriert, wenn sie an eine verwaiste Prozessgruppe übergeben wird, und die Gruppe des Anführers qualifiziert sich. Die Idee ist, dass SIGTSTP nichts aussetzen sollte, was von einem Benutzer nicht wieder aufgenommen werden kann.

In mkshoder yashkann auch suspendeine Subshell verwendet werden, um sich auszusetzen:

$ (set -x; sleep 1; suspend; sleep 2)
+ sleep 1
+ suspend
[1] + Stopped(SIGSTOP)     (set -x; sleep 1; suspend; sleep 2)
$ fg
[1] (set -x; sleep 1; suspend; sleep 2)
+ sleep 2

Das würde nicht funktionieren, zshwenn SIGTSTP anstelle des Aufrufers an die Hauptprozessgruppe gesendet wird. In jeder Shell, die killeingebaut ist, kann man immer kill -s TSTP 0stattdessen verwenden.

Stéphane Chazelas
quelle
4
Sie können eine übliche Verwendung für suspend anführen: in bash (und wahrscheinlich vielen Shells): als Sie einen langen Befehl gestartet haben und ihn nicht unterbrechen möchten, aber wenn Sie dies im Hintergrund getan haben (dh Sie möchten, command .... &aber Sie) vergaß das &und wünschte nun, Sie könnten es hinzufügen, ohne den Befehl zu unterbrechen): Sie können: ctrl-zund dann bgFolgendes eingeben:, um die letzte angehaltene Aufgabe im Hintergrund fortzusetzen. (oder bg %num dies mit der Aufgabennummer zu tun n. Verwenden Sie diese Option jobs, um eine Liste der angehaltenen oder ausgeführten Aufgaben
abzurufen.
5
@OlivierDulac, das würde nicht erklären, wozu der eigentliche suspend Befehl dient.
Wildcard