Какова цель встроенной команды bash `suspend`?

22

Я напечатал help suspendи получил это краткое объяснение:

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.

Насколько я понимаю, это: я suspendпечатаю, и терминал зависает, даже strg + c не может разморозить его. Но когда я открываю другой терминал и ищу PID для kill -SIGCONT PID-NRзамороженного терминала и набираю сигнал SIGCONT, он отправляется на замороженный терминал и оттаивает его, так что он размораживается.

Но какова реальная цель приостановки терминала? Какие ежедневные приложения характерны для него? Что имели в виду люди, которые сделали его встроенной оболочкой?

sharkant
источник
2
избегать запуска внешних программ (kill) для приостановки.
Ипор Сирсер

Ответы:

23

Если вы запускаете оболочку из другой оболочки, вы можете приостановить внутреннюю. Скажите, когда используете su, и хотите на мгновение вернуться к обычному пользователю:

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

(Если вы сделаете это, не забудьте открыть привилегированную оболочку в фоновом режиме ...)

Точно так же, если вы выйдете в оболочку из какой-либо другой программы ( !например less, из команды ), вы все равно можете приостановить ее. Но я бы не ожидал, что многие другие программы справятся с этим, когда они запустят подпроцесс, который затем приостанавливается.

ilkkachu
источник
1
Я просто попытался запустить vim, и сделал, :shчтобы получить subshell (в частности, zshsubshell). Запуск suspendзапихнул меня в оригинальную оболочку (она приостановила как subshell, так и vim).
Кевин
1
@Kevin, zshкажется умнее, чем bash, я пытался сбежать от обоих lessи vi(от Debian vim.tiny): zshостановил родительское приложение, bashповесил все это. bashк bashработам , хотя.
ilkkachu
1
я не знал, что то, что я печатаю sudo su subhell запускается. когда я набираю suspend в основной оболочке, оболочка просто зависает, но, как вы показали, когда я помещаю ее внутри subshell, я автоматически возвращаюсь к основной оболочке.
sharkant
25

Это эквивалентно нажатию Ctrl+Zв других командах.

Он приостанавливает оболочку и возвращает управление родительской оболочке или процессу, если таковые имеются.

Пример:

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

Эта функция появилась в csh, оболочке BSD (откуда происходит управление заданиями) в начале 80-х годов .

В AT & T kshэто встроенный псевдоним для kill -s STOP $$( да, без кавычек! )

В вашем случае это bashбыл, вероятно, тот, который был запущен непосредственно эмулятором терминала. И ваш эмулятор терминала не ожидал, что процесс будет приостановлен.

Это bashбыл лидер сессии. Если лидер сеанса приостановлен, если мы возьмем представление о старых временных терминалах, у пользователя не будет возможности возобновить его.

bashадреса, отказываясь, suspendесли это оболочка входа в систему. Но в вашем случае ваш эмулятор терминала, вероятно, не запускается bashв режиме входа в систему, так что защита не на месте.

zshи mkshне имеют проблемы, потому что они посылают SIGTSTP(тот, который также был отправлен Ctrl+Z) сигнал, такой как csh вместо SIGSTOP(и в группу процессов вызывающей стороны для mkshкак в csh, и в главную группу процессов оболочки для zsh, а не сам $$процесс ). SIGTSTPигнорируется при доставке в осиротевшую группу процессов, а группа лидера квалифицируется. Идея состоит в том, что SIGTSTP не должен приостанавливать то, что не может быть возобновлено пользователем.

В mkshили yash, также можно использовать suspendдля приостановки подоболочки:

$ (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

Это не сработает zsh, так как SIGTSTP отправляется основной группе процессов, а не вызывающей стороне. В любой оболочке, которая имеет killвстроенную функцию, всегда можно использовать kill -s TSTP 0вместо нее .

Стефан Шазелас
источник
4
Вы можете сослаться на общее использование для приостановки: в bash (и, вероятно, во многих оболочках): когда вы запускаете длинную команду и не хотите прерывать ее, но хотите, чтобы вы делали это в фоновом режиме (то есть вы хотите, command .... &но вы забыл &и теперь хотел бы добавить его, не прерывая команду): вы можете:, ctrl-zа затем введите:, bgчтобы возобновить последнюю приостановленную задачу в фоновом режиме. (или bg %nсделать это с помощью номера задачи n. Используйте jobsдля получения списка приостановленных или запущенных задач)
Оливье Дюлак
5
@OlivierDulac, это не объясняет, для чего нужна настоящая suspend команда .
подстановочный знак