0

I have a doubt because I understand that:

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

output should be a list contining all system's users, instead of that I get the second row which is filled with x, when I want the first one; why?

Also, in this script you pass as argument a number and you see the list of user who have equal and more files than the value entered:

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

and it works ok, but why it doesn't works:

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

Its outputs is the raw string without appending user's names why?

steeldriver
  • 81,074
Yone
  • 219

1 Answers1

2

You seem to have mixed up the syntax of for and while. for executes a sequence of commands for each element in a list; the syntax is for VARIABLE in VALUES; do COMMANDS; done: the keyword in separates the variable name from the list of values. while executes a sequence of commands while another sequence of commands is true; the syntax is while COMMANDS; do COMMANDS; done.

The command read reads one line and splits it into fields. The arguments of read are the variables to set the field values to. So read in USUARIO sets in to the first field and USUARIO to the second field, or if there are more than two fields (which is the case in your scenario) USUARIO is set to all the remaining fields (inner separators included). Each call to read reads a single line, and each loop iteration thus processes one line of the input.

Thus, to print the user names only, you need to write

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

Regarding the second question (but next time, please don't ask unrelated questions together), the problem is that each command in a pipeline is executed in a subshell, so variables set in one of them aren't visible outside of the pipeline. See Why is my variable local one 'while read' loop, but not in another seemingly similar loop?