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 for
y while
. for
ejecuta 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; done
in
while
while COMMANDS; do COMMANDS; done
El comando read
lee una línea y la divide en campos. Los argumentos de read
son las variables para establecer los valores del campo. Por lo tanto, read in USUARIO
se establece in
en el primer campo y USUARIO
en el segundo campo, o si hay más de dos campos (como es el caso en su escenario), USUARIO
se establece en todos los campos restantes (separadores internos incluidos). Cada llamada a read
lee 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?