Por que alguns comandos 'interrompem' o terminal até que eles terminem?

21

Às vezes você executa um programa a partir do terminal, digamos, lxpanel . O terminal não vai deixá-lo voltar ao prompt, ele irá travar. Você pode pressionar Ctrl + C para voltar ao prompt, mas isso matará lxpanel . No entanto, pressionando Alt + F2 (que abre uma janela para receber um comando) e executando lxpanel funciona normalmente.

Por que isso? O que é diferente entre executar um comando a partir do terminal e da janela 'run' que aparece quando você pressiona Alt + F2 ?

lxpanel aqui foi usado apenas como exemplo. Eu experimentei isso com vários programas

    
por sqram 26.12.2011 / 08:11

4 respostas

27

Por padrão, o terminal executará o programa em primeiro plano, assim você não voltará ao shell até que o programa termine. Isso é útil para programas que lêem stdin e / ou escrevem para stdout - geralmente você não quer que muitos deles sejam executados ao mesmo tempo. Se você quer que um programa seja executado em segundo plano, você pode começar assim:

$ lxpanel &

Ou se já estiver rodando, você pode suspendê-lo com Ctrl + Z e então executar bg para movê-lo para o segundo plano. De qualquer forma você vai acabar com um novo prompt de shell, mas o programa ainda está em execução e sua saída aparecerá no terminal (para que possa aparecer de repente enquanto você está no meio da digitação)

Alguns programas (normalmente daemons) irão separar um processo separado quando eles iniciarem, e então deixarão o processo principal sair imediatamente. Isso permite que o programa continue rodando sem bloquear seu shell

    
por 26.12.2011 / 08:27
5

Quando você inicia um programa em um terminal, o terminal fica "travado" até que seu programa seja interrompido. Pressionando Ctrl + c você está fechando seu programa e, assim, retorna ao prompt. Você verá isso com todos os aplicativos GUI, tente o Firefox, por exemplo.

Quando você usa algum outro método, como Alt + F2 ou clicando nos menus, seu programa é iniciado em segundo plano, então nada de estranho acontece (e não há prompt de comando de qualquer maneira).

Se você ainda quiser iniciar aplicativos GUI a partir do terminal, anexe & no final do seu comando, assim

lxpanel &

Isto diz ao terminal para rodar lxpanel no fundo e dar outro prompt imediatamente.

    
por 26.12.2011 / 08:28
3

Os programas são executados através de um shell executado no primeiro plano desse shell por padrão. Isso faz com que o shell suspenda a operação e direcione stdin / stdout / sterr do terminal para o programa. Os programas executados pelo ambiente de área de trabalho são bifurcados , o que faz com que eles sejam executados independentemente do programa que os executou. Isso pode ser simulado na maioria dos shells, anexando um & ao comando, embora isso ainda conecte o std * ao terminal (embora a leitura de stdin em um programa em segundo plano tenha mais complicações).

    
por 26.12.2011 / 08:28
2

O & fundos bem, exceto para programas que voltam exigindo interação do console mais tarde (por exemplo, um "apt -y update &" que eventualmente entra no estado STOP, pois está querendo perguntar ao usuário uma pergunta "realmente realmente forçar" muito mais tarde. ... quando ninguém está mais assistindo).

Para tapar esse buraco e informar o processo que um terminal nunca estará realmente disponível para ele, eu adiciono um < & - a alguns dos meus comandos, separando-os completamente do terminal ativo dizendo que STDIN não é mais possível . Certifique-se de que / bin / bash é o seu shell se você usar isso. O script continuará registrando quaisquer erros relacionados ao não-pseudo-terminal disponível para lançar qualquer prompt.

Por exemplo:

'./runme.sh &> runme.log <&- & disown'

é a minha maneira final de se desassociar da sessão de terminal atual. Tanto STDOUT quanto STDERR são logados em runme.log, não importa se seu console ou shell terminam mais cedo ou se você efetua logout / su para uma conta diferente (não há lixo terminal no runme), e obrigado a negar até mesmo o pai-filho A relação de PID é removida.

ATUALIZAÇÃO: mesmo com isso eu tive problemas com um semáforo associando-o ao nome do pai original, então agora eu recomendo:

at now <<< "(cmd1; cmd2; etc.) &> logfile.log"

Claro, remova o & > se você deseja receber o email da saída do CRON, ou redirecione tudo para / dev / null em vez de um arquivo.

    
por 26.12.2011 / 22:09