Usando read, IFS e enquanto juntos dúvidas

Usando read, IFS e enquanto juntos dúvidas

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 contendo todos os usuários do sistema, ao invés disso eu recebo a segunda linha que é preenchida com x, quando eu quero a primeira; por que?

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

#!/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 por que 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 anexar os nomes dos usuários, por quê?

Responder1

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

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

Assim, para imprimir apenas 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, por favor, não façam perguntas não relacionadas juntas), o problema é que cada comando em um pipeline é executado em um subshell, então as variáveis ​​definidas em um deles não são visíveis fora do pipeline. VerPor que minha variável local está em um loop 'durante a leitura', mas não em outro loop aparentemente semelhante?

informação relacionada