У меня есть сомнения, потому что я понимаю, что:
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; done
in
while
while COMMANDS; do COMMANDS; done
Команда read
считывает одну строку и разбивает ее на поля. Аргументы read
— это переменные, в которые задаются значения полей. Так что read in USUARIO
устанавливает in
первое поле и USUARIO
второе поле, или, если полей больше двух (что имеет место в вашем сценарии), USUARIO
устанавливает все оставшиеся поля (включая внутренние разделители). Каждый вызов read
считывает одну строку, и каждая итерация цикла, таким образом, обрабатывает одну строку ввода.
Таким образом, чтобы напечатать только имена пользователей, вам нужно написать
while IFS=: read USUARIO rest
do
echo "$USUARIO"
done
Что касается второго вопроса (но в следующий раз, пожалуйста, не задавайте несвязанные вопросы вместе), проблема в том, что каждая команда в конвейере выполняется в подоболочке, поэтому переменные, заданные в одной из них, не видны за пределами конвейера. СмотритеПочему моя переменная находится локально в цикле «while read», но не в другом, казалось бы, похожем цикле?