В современных оболочках, таких как bash и zsh, у вас есть очень полезный перенаправитель `<<< ', который принимает строку в качестве входных данных. Так что вы бы сделали
while IFS= read -r line ; do echo $line; done <<< "$variable"
В противном случае вы всегда можете сделать
echo "$variable" | while IFS= read -r line ; do echo $line; done
Утилита read
будет ждать пока не будут введены данные, поэтому
read username
не вернется, пока пользователь не введет что-то, что оболочка затем сохранит как $username
.
Если вы под «ожиданием» подразумеваете «цикл до тех пор, пока не будет введено действительное имя пользователя», вы можете сделать что-то вроде
while true; do
read -p 'Enter username: ' username
if id "$username" >/dev/null 2>&1; then
printf 'Username "%s" is valid\n' "$username"
break
fi
printf 'Username "%s" is not valid\n' "$username"
echo 'Try again...'
done
Это переходит в бесконечный цикл, который завершится только после того, как пользователь введет действительное имя пользователя. Валидность проверяется с помощью утилиты id
, которую, похоже, использует и ваш код. Если утилита завершается без ошибки, цикл выходит через break
.
После этого цикла вы знаете, что у вас есть допустимое имя пользователя в $username
.
Чтобы проверить, вошел ли пользователь в систему, вы можете использовать who
, как вы сделали здесь (с небольшими изменениями):
if who | grep -q "^$username\>"; then
printf 'User "%s" is logged on\n' "$username"
else
printf 'User "%s" is not logged on\n' "$username"
fi
Имена пользователей находятся в первом столбце вывода who
. Поэтому мы привязываем имя пользователя к началу строки с помощью ^
. Мы также следим за тем, чтобы граница слова в конце имени пользователя соответствовала \>
(, чтобы мы не обнаружили пользователя arthur
, когда на самом деле ищемart
).
Вместо who
мы могли бы иметь утилиту users
.
Чтобы получить полное имя пользователя, выполните
name=$( getent passwd "$username" | cut -d : -f 5 | cut -d, -f 1 )
Утилита getent
используется, помимо прочего, для получения базы данных паролей или записи из нее. Здесь мы используем его, чтобы получить запись базы данных паролей для конкретного интересующего нас пользователя. Затем мы извлекаем полное имя из первого значения поля GECOS, разделенного запятой -.
Обратите внимание, что мы могли бы использовать getent
в качестве утилиты для проверки действительных имен пользователей с (, так как она возвращает не -нулевой статус выхода, если вы используете недопустимое имя пользователя с ним ), и таким образом получил полное имя пользователя в процессе без необходимости делать другой запрос впоследствии.
Все вместе:
#!/bin/bash
while true; do
read -p 'Enter username: ' username
if id "$username" >/dev/null 2>&1; then
printf 'Username "%s" is valid\n' "$username"
break
fi
printf 'Username "%s" is not valid\n' "$username"
echo 'Try again...'
done
name=$( getent passwd "$username" | cut -d : -f 5 | cut -d, -f 1 )
printf 'Full name of "%s" is %s\n' "$username" "$name"
if who | grep -q "^$username"; then
printf '%s is logged on\n' "$name"
else
printf '%s is not logged on\n' "$name"
fi
Вы можете задать результат при ошибке, чтобы войти в цикл, выполнить работу внутри цикла и во время следующей итерации запросить реальный результат.
Что-то вроде:
#!/bin/bash
ok=1
while [ $ok -gt 0 ]; do
read one
< your check of $one >
ok=$?
done