Por que esse loop infinito não usa meus recursos do sistema?

4

Eu fiz o seguinte na BASH:

while true;do bash;done

Eu escrevi este forro, mas eu não tinha certeza se:

  • permanece no shell principal e no pai como muitos subshells quando fica sem memória ou alguma outra coisa.
  • o shell principal gera um subshell, e este subshell gera um subshell até que essa linhagem fique sem memória ou alguma outra coisa.

Mas, eu suponho que é o segundo caso, porque uma vez eu corri o liner, eu recebi logo após o meu retorno e comecei a digitar exit e outra exit e exit, exit, exit ... e eu ainda estava não de volta na casca principal.

Agora, como muitas sub-camadas foram abertas e cada uma é um programa, achei que cada uma deveria ter seu próprio PID.

Então eu fiz:

ps aux | grep bash

esperando ver muitos processos com bash em seus nomes.

No entanto, nada como isso, havia apenas dois shells bash.

Como é possível, acho que tenho uma ideia muito errada sobre processos, shells, subshells e PIDs, mas não sei onde.

    
por sharkant 12.05.2017 / 16:30

2 respostas

6

Seu loop inicia uma única sessão de shell interativa em cada iteração.

A sessão interativa fornece um prompt (já que é interativo). Ao sair, ele retorna o controle para o loop, que inicia outro shell interativo.

É por isso que você não obtém grandes quantidades de bash processos de uma vez, apenas dois, o pai que executa o loop e o filho que fornece o novo prompt.

O loop também pode ser escrito

while true; do bash; done

O utilitário true não recebe um argumento, apenas retorna um valor de saída zero que é interpretado como "true" pelo shell.

Se você quisesse uma explosão de bash processos (a chamada "fork-bomb"), você pode ter escrito

while true; do { bash & }; done

Isso iniciaria uma sessão bash interativa em cada iteração do loop, mas como processa em segundo plano . Como as sessões são iniciadas como processos em segundo plano, o loop não esperará o último processo bash terminar antes de iniciar o próximo.

Você pode ter que reiniciar seu sistema para se recuperar disso.

Esta fork-bomb é mais benigna do que poderia ser, já que só inicia um novo processo em cada iteração. Outros podem iniciar processos de maneira exponencial.

    
por 12.05.2017 / 16:38
6

Seu loop está iniciando um número infinito de shells, mas um após o outro, não em paralelo. A primeira vez que o loop é executado, ele executa bash , que inicia um novo shell e exibe o prompt. O shell pai aguarda que esse shell saia; isso acontece quando você digita exit , saindo do shell filho e retornando ao shell pai, que roda o loop novamente e executa bash , que inicia um novo shell e exibe o prompt ...

Você pode exibir seu nível de shell executando

echo $SHLVL

Você verá que esse número não muda quando você digita comandos exit sucessivos.

    
por 12.05.2017 / 16:34