Qual é o significado de & no final de um comando?

12

Eu tenho uma linha de script de inicialização:

pyprogramm >> /dev/null  2>&1 &

Significados:

>> /dev/null - redirect stdout to null device
2>&1 - redirect stderr to stdout (that is redirected to null device)

mas o que significa o último &?

vico
fonte

Respostas:

16

O que é o & terminator?

O &operador à direita no final de um comando é usado para colocar os comandos em segundo plano. Esta é realmente uma sintaxe padrão especificada pelo padrão POSIX :

Listas assíncronas

Se um comando é finalizado pelo operador de controle ('&'), o shell deve executar o comando de forma assíncrona em um subshell. Isso significa que o shell não deve esperar o comando terminar antes de executar o próximo comando.

O formato para executar um comando em segundo plano é:

command1 & [command2 & ...]

O objetivo dos comandos de segundo plano é executar um comando sem o shell principal no script ou o shell interativo aguardando pelo comando, o que bloquearia a execução de outros comandos e causaria inconveniência para o usuário aguardar. Isso é útil para iniciar comandos de longa execução, mas você precisa continuar trabalhando no shell atual. Como você pode imaginar, isso se originou do momento em que não havia emuladores de terminal com várias guias, mas os terminais eram hardware físico real conectado ao próprio computador.

A partir da definição, você pode ver que &também serve como terminador de comando para listas de comandos, assim como ;faz. No seu exemplo específico, pyprogramm >> /dev/null 2>&1 &há apenas um comando na lista.

Sequencial ; listas vs assíncronas e listas

De forma geral,

echo Hello ; echo World ;

e

echo Hello & echo World &

Existem dois exemplos de listas terminadas pelos operadores ;e &. Uma diferença é que a &lista encerrada terá entrada conectada /dev/nullse o controle de trabalho estiver desativado:

Se o controle da tarefa estiver desativado (consulte set, -m), a entrada padrão para uma lista assíncrona, antes que qualquer redirecionamento explícito seja executado, será considerada como atribuída a um arquivo que possui as mesmas propriedades que / dev / null. Isso não acontecerá se o controle do trabalho estiver ativado. Em todos os casos, o redirecionamento explícito da entrada padrão substituirá essa atividade.

Na lista sequencial, no entanto, cada comando ainda está stdinconectado ao terminal se não houver redirecionamentos explícitos.

Observe também que, a partir da definição mencionada anteriormente, &executa comandos no subshell. Por outro lado, a ;lista finalizada é executada no shell atual. Também há diferença nos status de saída. Para &o padrão diz:

O status de saída de uma lista assíncrona deve ser zero.

Isso é significativo quando você deseja colocar vários comandos em segundo plano. Ao escrever um script ou comando, você terá que escolher comandos para os quais não se importa se eles falharam ou não, ou terá que encontrar uma maneira de lidar com o status de saída diferente de zero (erro). No seu exemplo específico, a pyprogramm >> /dev/null 2>&1 &execução em segundo plano deve ter alguma maneira de indicar se falhou ou não; no entanto, ao julgar que você usa, 2>&1você está ocultando a saída de erro ao redirecionar e provavelmente supõe que o script não deve falhar.

Por outro lado, o ;status de saída é definido como:

O status de saída de uma lista seqüencial deve ser o status de saída do último comando da lista.

Novamente, isso tem implicações em como você escreve uma lista seqüencial de comandos na linha de comando e como deseja que as coisas sejam tratadas se alguns dos comandos da lista falharem.


Notas laterais e leitura adicional

  • O fato de que este é o meio de definição POSIX que todos Bourne-como conchas, significado bash, dashe kshdeve apoiá-lo.

  • &no redirecionamento é diferente de &como terminador de comando. Significa duplicar (copiar) o objeto descritor de arquivo. Consulte O que significa e exatamente no redirecionamento de saída?

  • Em bashhá também |&operador (observe nenhum espaço entre o tubo e comercial). No manual do bash :

    Se | & for usado, o erro padrão do comando, além de sua saída padrão, será conectado à entrada padrão do command2 através do pipe; é uma abreviação de 2> & 1 |. Esse redirecionamento implícito do erro padrão para a saída padrão é realizado após qualquer redirecionamento especificado pelo comando.

Sergiy Kolodyazhnyy
fonte
2
O que você diz sobre &ocultar a saída não parece correto. O parágrafo do padrão que você está citando fala de entrada , não de saída . O motivo da distinção entre o controle de tarefas ser ativado ou não é que um processo em segundo plano que tenta ler a partir do tty será suspenso. Nesse ponto, você precisa usar o controle de tarefas para colocá-lo em primeiro plano para fornecer a entrada que está aguardando. Tudo isso não pode ser feito sem o controle do trabalho e, portanto, se o controle do trabalho estiver desativado, o stdin precisará ser redirecionado /dev/nullou equivalente.
kasperd
Também vi um erro na sua edição. Em um lugar, você escreveu ativado, onde deveria ter desativado.
kasperd
@ Kasperd Sim, eu estava apenas relendo a página POSIX quando percebi isso também. Já fixa. Deixe-me saber se mais alguma coisa precisa ser editada. Obrigado :)
Sergiy Kolodyazhnyy
3

Isso significa executar o comando em segundo plano. O script de chamada continua em vez de bloquear até que o comando chamado seja concluído.

Robert Longson
fonte
0

&isso retorna o controle do script para o sistema operacional, mas envia a resposta para o plano de fundo, não porque nohupela envia diretamente toda a execução

Bryro
fonte