Eu estava apenas executando alguns comandos em um terminal e comecei a pensar: o Unix / Linux usa atalhos ao executar comandos canalizados?
Por exemplo, digamos que eu tenha um arquivo com um milhão de linhas, as 10 primeiras contendo hello world
. Se você executar o comando grep "hello world" file | head
, o primeiro comando será interrompido assim que encontrar 10 linhas ou continuará pesquisando primeiro o arquivo inteiro?
command-line
pipe
utilities
efficiency
DisgruntledGoat
fonte
fonte
-m
argumento.Respostas:
Tipo de. O shell não tem idéia do que os comandos que você está executando farão, apenas conecta a saída de um à entrada do outro.
Se
grep
encontrar mais de 10 linhas que dizem "olá mundo",head
terá todas as 10 linhas que deseja e feche o tubo. Isso fará comgrep
que seja morto com um SIGPIPE, portanto, não é necessário continuar a varredura de um arquivo muito grande.fonte
grep
que continuaria enviando saída para um vazio, semelhante a/dev/null
Quando um programa tenta gravar em um canal e não há leitura de processo nesse canal, o programa gravador recebe um sinal SIGPIPE . A ação padrão quando um programa recebe o SIGPIPE é finalizar o programa. Um programa pode optar por ignorar o sinal SIGPIPE; nesse caso, a gravação retorna um erro (
EPIPE
).No seu exemplo, aqui está uma linha do tempo do que acontece:
grep
ehead
são iniciados em paralelo.grep
lê alguma entrada, começa a processá-la.grep
produz um primeiro pedaço de saída.head
lê esse primeiro pedaço e escreve.grep
pode terminar primeiro), eventualmente,head
será impresso o número desejado de linhas. Neste ponto,head
sai.grep
ehead
,grep
pode ter acumulado alguns dados e ainda não os impresso. No momento dahead
saída,grep
pode estar lendo a entrada ou fazendo um processamento interno; nesse caso, continuará a fazê-lo.grep
breve gravará os dados processados. Nesse ponto, ele receberá um SIGPIPE e morrerá.É provável que
grep
processe um pouco mais do que o estritamente necessário, mas geralmente apenas alguns kilobytes:head
normalmente lê em pedaços de alguns kilobytes (porque é mais eficiente do que emitir umaread
chamada do sistema para cada byte - esse comportamento é chamado de buffer), portanto, o restante do último pedaço após a última linha desejada é descartado.grep
pode ter acumulado alguns dados prontos para se tornar um pedaço de saída (buffer novamente). Ele receberá o SIGPIPE quando estiver tentando liberar seu buffer de saída.Em suma, o sistema foi projetado com precisão para que os utilitários de filtragem se comportem naturalmente com eficiência. Os programas que precisam continuar quando o canal de saída desaparece devem ignorar o sinal SIGPIPE.
fonte
No entanto, o pipeline funciona assim: primeiro executa o primeiro comando e depois o segundo comando no seu caso.
Ou seja, vamos ter
A|B
o comando dado. Então é incerto seA
ouB
começa primeiro. Eles podem começar exatamente ao mesmo tempo se houver várias CPUs. Um canal pode conter uma quantidade indefinida, mas finita, de dados.Se B tentar ler do canal, mas nenhum dado estiver disponível,
B
esperará até que os dados cheguem. SeB
estava lendo um disco,B
pode ter o mesmo problema e precisar aguardar até que a leitura do disco termine. Uma analogia mais próxima seria a leitura de um teclado. Lá,B
seria necessário aguardar o usuário digitar. Mas em todos esses casos, B iniciou uma operação de "leitura" e deve esperar até que seja concluída. Mas seB
é um comando que precisa apenas de saída parcialA
, após certo ponto em queB
o nível de entrada é atingidoA
será eliminado pelo SIGPIPESe
A
tentar gravar no tubo e o tubo estiver cheio,A
espere que haja espaço no tubo livre.A
poderia ter o mesmo problema se estivesse gravando em um terminal. Um terminal possui controle de fluxo e pode moderar o ritmo dos dados. De qualquer forma, paraA
, iniciou uma operação de "gravação" e aguardará até que a operação de gravação seja concluída.A
eB
estão se comportando como co-processos, embora nem todos os co-processos se comuniquem com um canal. Nenhum deles está no controle total do outro.fonte
head
saídas), um sinal SIGPIPE ocorre no programa e o comportamento padrão é sair.grep
não tem controle direto do canal (está apenas recebendo dados) e o canal não tem controle diretogrep
(está apenas enviando dados) ...O que
grep
, ou qualquer outro programa faz, depende inteiramente da lógica interna do programa. Se você disser,grep
por meio das opções da linha de comando, para fazer uma saída antecipada quando encontrada , será o caso, caso contrário, será executado no final do arquivo procurando o padrão ...O terminal também está bastante desconectado do funcionamento interno
grep
e dasshell
ações da tubulação ... O terminal é basicamente apenas uma plataforma de lançamento e exibição de saída ...fonte