Por que o comando de saída não sai do loop aninhado? [duplicado]

1

Eu tenho o seguinte script. Ele imprime todos os primeiros caracteres para o console a partir do passwd, mas minha expectativa era obter apenas um caractere e terminar o programa.

#!/bin/sh 

cat /etc/passwd |
while read -r line
do
    echo ${line} |
        grep -o . |
        while read char
        do
            echo ${char}   
            exit 1       
        done
done

Saída real:

r
b
d
a
(etc)

Resultado esperado:

r
    
por Tamás Szabó 01.03.2016 / 18:14

2 respostas

0

A maioria dos shells parecidos com Bourne, exceto zsh e ksh , executam cada parte de pipelines em subshells. Supondo que você não use zsh ou ksh , então, no seu script, a última parte do pipiline foi executada em subshell, portanto exit encerra essa sub-shell em vez do shell atual.

Você receberá o resultado desejado em zsh ou ksh .

De qualquer forma, esses códigos têm muitas falhas:

Se tudo o que você deseja é obter o primeiro caractere no arquivo:

dd bs=1 count=1 if=/etc/passwd 2>/dev/null

ou com o GNU dd :

dd status=none bs=1 count=1 if=/etc/passwd

Funciona apenas com caracteres ASCII. Para caracteres de multibyte:

LC_ALL=en_US.utf8 awk '{print substr($0,1,1);exit}'

Altere LC_ALL para qual localidade seu texto pertence.

    
por 01.03.2016 / 18:32
0

Pipes cria sub-shells. O shell embutido exit termina um shell. Resultando no comportamento inesperado no seu caso:

> exit | exit | echo wow
wow

Sugiro olhar para a seção Pipelines em man bash . Veja também help exit .

    
por 01.03.2016 / 18:43