Usando o read, IFS e enquanto juntos duvidam

0

Eu tenho uma dúvida porque entendo que:

exec 0</etc/passwd
IFS=:
while read in USUARIO
do
    echo $USUARIO
done

a saída deve ser uma lista que contenha todos os usuários do sistema, em vez de eu obter a segunda linha que é preenchida com x, quando eu quiser o primeiro; por quê?

Além disso, neste script, você passa como argumento um número e vê a lista de usuários com arquivos iguais e mais do que o valor digitado:

#!/bin/bash

if [[ ( $# -eq 1) && ( $1==[0-9][0-9]* )]]
then
    echo "User with $1 files or more "
    cut -d':' -f1 /etc/passwd | while IFS= read -r USUARIO
    do
        if [[ $( find / -user $USUARIO -print | wc -l ) -ge $1 ]]
        then

            echo $USUARIO
        fi
    done
exit 0
else
    printf "Error: $0 int"
    exit 1
fi

e funciona bem, mas porque não funciona:

#!/bin/bash

if [[ ( $# -eq 1) && ( $1==[0-9][0-9]* )]]
then
    LIST="Users with more or $1 files: "
    cut -d':' -f1 /etc/passwd | while IFS= read -r USUARIO
    do
        if [[ $( find / -user $USUARIO -print | wc -l ) -ge $1 ]]
        then

            LIST="$LIST $USUARIO"
        fi
    done
echo $LIST
exit 0
else
    printf "Error $0 int"
    exit 1
fi

Suas saídas são a string bruta sem acrescentar os nomes dos usuários por quê?

    
por enoy 29.10.2016 / 19:21

1 resposta

1

Você parece ter misturado a sintaxe de for e while . for executa uma seqüência de comandos para cada elemento em uma lista; a sintaxe é for VARIABLE in VALUES; do COMMANDS; done : a palavra-chave in separa o nome da variável da lista de valores. while executa uma seqüência de comandos enquanto outra seqüência de comandos é verdadeira; a sintaxe é while COMMANDS; do COMMANDS; done .

O comando read lê uma linha e a divide em campos. Os argumentos de read são as variáveis para definir os valores do campo. Portanto read in USUARIO define in para o primeiro campo e USUARIO para o segundo campo, ou se houver mais de dois campos (o que é o caso em seu cenário) USUARIO é definido para todos os campos restantes (interno separadores incluídos). Cada chamada para read lê uma única linha e cada iteração de loop, portanto, processa uma linha da entrada.

Assim, para imprimir somente os nomes de usuário, você precisa escrever

while IFS=: read USUARIO rest
do
    echo "$USUARIO"
done

Em relação à segunda pergunta (mas da próxima vez, não faça perguntas não relacionadas), o problema é que cada comando em um pipeline é executado em uma sub-shell, então as variáveis definidas em uma delas não são visíveis fora da o gasoduto. Veja Por que minha variável local é um loop 'while read', mas não em outro loop aparentemente similar?

    
por 30.10.2016 / 01:45

Tags