Используя read, IFS и while вместе сомнения

Используя read, IFS и while вместе сомнения

У меня есть сомнения, потому что я понимаю, что:

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

на выходе должен быть список, содержащий всех пользователей системы, вместо этого я получаю вторую строку, заполненную x, когда мне нужна первая; почему?

Кроме того, в этом скрипте вы передаете в качестве аргумента число и видите список пользователей, у которых количество файлов равно или больше введенного значения:

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

и это работает нормально, но почему это не работает:

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

Почему на выходе получается необработанная строка без добавления имен пользователей?

решение1

Похоже, вы перепутали синтаксис forи while. forвыполняет последовательность команд для каждого элемента в списке; синтаксис такой : ключевое слово отделяет имя переменной от списка значений. выполняет последовательность команд, пока другая последовательность команд является истинной; синтаксис такой .for VARIABLE in VALUES; do COMMANDS; doneinwhilewhile COMMANDS; do COMMANDS; done

Команда readсчитывает одну строку и разбивает ее на поля. Аргументы read— это переменные, в которые задаются значения полей. Так что read in USUARIOустанавливает inпервое поле и USUARIOвторое поле, или, если полей больше двух (что имеет место в вашем сценарии), USUARIOустанавливает все оставшиеся поля (включая внутренние разделители). Каждый вызов readсчитывает одну строку, и каждая итерация цикла, таким образом, обрабатывает одну строку ввода.

Таким образом, чтобы напечатать только имена пользователей, вам нужно написать

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

Что касается второго вопроса (но в следующий раз, пожалуйста, не задавайте несвязанные вопросы вместе), проблема в том, что каждая команда в конвейере выполняется в подоболочке, поэтому переменные, заданные в одной из них, не видны за пределами конвейера. СмотритеПочему моя переменная находится локально в цикле «while read», но не в другом, казалось бы, похожем цикле?

Связанный контент