Qual é o objetivo do comando bash 'suspend' builtin?

20

Eu digitei help suspend e recebi esta breve explicação:

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.

Como eu entendo isso: eu digito suspend e o terminal congela, nem mesmo strg + c pode descongelá-lo. Mas quando eu abro outro terminal e procuro o PID para o congelado e digito kill -SIGCONT PID-NR um sinal SIGCONT é enviado para o terminal congelado e descongela, para que ele seja descongelado.

Mas qual é o propósito real de suspender um terminal? Quais aplicativos diários são típicos para isso? O que as pessoas que fizeram disso uma shell builtin têm em mente?

    
por sharkant 11.05.2017 / 14:11

2 respostas

22

Se você iniciar um shell a partir de outro shell, poderá suspender o interno. Diga quando usar su e quiser voltar para o usuário normal por um momento:

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

(Se você fizer isso, não esqueça o shell privilegiado aberto em segundo plano ...)

Da mesma forma, se você escapar para um shell de algum outro programa (o comando ! , por exemplo, less ), ainda é possível suspender o shell. Mas eu não esperaria muitos outros programas para lidar com isso muito bem quando eles lançam um subprocesso, que então se suspende.

    
por 11.05.2017 / 14:31
25

Isso é o equivalente a pressionar Ctrl + Z em outros comandos.

Ele suspende o shell e retorna o controle ao shell pai ou ao processo, se houver algum.

Exemplo:

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

O recurso vem do csh, o shell do BSD (de onde vem o controle de trabalho) no início dos anos 80 .

Em AT & T ksh , é um alias interno para kill -s STOP $$ ( sim, sem as aspas! )

No seu caso, bash foi provavelmente o iniciado diretamente pelo emulador de terminal. E o seu emulador de terminal não esperava que o processo fosse suspenso.

Esse bash foi um líder de sessão. Se o líder da sessão estiver suspenso, se considerarmos os terminais antigos, o usuário não terá como retomá-lo.

bash corrige isso ao se recusar a suspend se for um shell de login. Mas no seu caso, o emulador de terminal provavelmente não inicia o bash no modo de login, então essa salvaguarda não está em vigor.

zsh e mksh não têm problema porque enviam um sinal SIGTSTP (o que também é enviado com Z + ) como csh em vez de SIGSTOP (e para o grupo de processos do chamador para mksh como em csh e para o grupo de processos principal do shell para zsh , não apenas para o processo $$ ). SIGTSTP é ignorado quando entregue a um grupo de processos órfão e o grupo do líder se qualifica. A ideia é que o SIGTSTP não deve suspender algo que não seja recuperável por um usuário.

Em mksh ou yash , também é possível usar suspend para que uma subshell seja suspensa:

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

Isso não funcionaria com zsh que envia o SIGTSTP para o grupo de processos principal em vez do chamador. Em qualquer shell que tenha kill integrado, sempre é possível usar kill -s TSTP 0 .

    
por 11.05.2017 / 14:28