Usando lectura, IFS y dudas mientras estamos juntos.

Usando lectura, IFS y dudas mientras estamos juntos.

Tengo una duda porque entiendo que:

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

la salida debería ser una lista que contenga todos los usuarios del sistema, en lugar de eso, obtengo la segunda fila que se llena con x, cuando quiero la primera; ¿por qué?

Además, en este script pasas como argumento un número y ves la lista de usuarios que tienen archivos iguales y más que el valor ingresado:

#!/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

y funciona bien, pero por qué no 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

Su salida es la cadena sin formato sin agregar los nombres de los usuarios, ¿por qué?

Respuesta1

Parece que has confundido la sintaxis de fory while. forejecuta una secuencia de comandos para cada elemento de una lista; la sintaxis es : la palabra clave separa el nombre de la variable de la lista de valores. ejecuta una secuencia de comandos mientras otra secuencia de comandos es verdadera; la sintaxis es .for VARIABLE in VALUES; do COMMANDS; doneinwhilewhile COMMANDS; do COMMANDS; done

El comando readlee una línea y la divide en campos. Los argumentos de readson las variables para establecer los valores del campo. Por lo tanto, read in USUARIOse establece inen el primer campo y USUARIOen el segundo campo, o si hay más de dos campos (como es el caso en su escenario), USUARIOse establece en todos los campos restantes (separadores internos incluidos). Cada llamada a readlee una sola línea y, por lo tanto, cada iteración del bucle procesa una línea de la entrada.

Por lo tanto, para imprimir sólo los nombres de usuario, es necesario escribir

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

Con respecto a la segunda pregunta (pero la próxima vez, no hagan preguntas no relacionadas juntos), el problema es que cada comando en una canalización se ejecuta en un subshell, por lo que las variables establecidas en uno de ellos no son visibles fuera de la canalización. Ver¿Por qué mi variable local está en un bucle 'mientras se lee', pero no en otro bucle aparentemente similar?

información relacionada