Я работаю над сценарием для удаления пользователей из файла .txt, но предоставляю возможность удаления в качестве окончательного отказоустойчивого.
Текстовый файл называется badUsers.txt
Я в основном модифицирую этот скрипт, который, я знаю, работает:
cat badUsers.txt | while read user
echo "Deleting: ${user}"
echo userdel -r "${user}"
done
Это новая версия:
while true; do
read -p "Should ${user} be deleted from the system? : " yn
case $yn in
[Yy]* ) echo "Deleting: ${user}"
echo userdel -r "${user}"
break;;
[Nn]* ) echo "next user"
break;;
* ) echo "Please answer yes or no.";;
esac
done
Каждый раз, когда я запускаю его, я получаю бесконечный цикл, но я не уверен, почему. Что я здесь не так делаю?
Есть 3 вещи, с которыми вам нужно позаботиться:
В псевдокоде алгоритм будет выглядеть примерно так:
for each name N in the input file
ask if N should be interpreted as a user and deleted; wait for a reply R
if R is yes delete the user else skip
Что касается (3), мы можем повторно использовать ваш подход. Я исправил удаление эха, поскольку это предотвращает удаление пользователя.
Что касается (2), то существует как минимум 2 способа.
read -p "Should ${user} be deleted? (yN)" -r yn
case $yn in
...
esac
и
echo Should ${user} be deleted?
select yn in "Y" "N"
do
case $yn in
...
done
done
В отношении (1) существует по меньшей мере 2 метода.
for user in $(<badUsers.txt)
do
...
done
while read -r user
do
...
done < badUsers.txt
Последний метод аналогичен конструкции cat, которую вы используете выше, но предпочтителен, поскольку он допускает перенаправление файловых дескрипторов. Если мы предпочитаем методы, используемые в приведенном вами примере, мы получаем что-то вроде следующего.
while read -u 3 -r user
do
read -p "Should ${user} be deleted from the system? (yN)" -r yn
case $yn in
[Yy]) echo "Deleting: ${user}"
userdel -r -- "${user}" 2> /dev/null
;;
*) echo next user
;;
esac
done 3< badUsers.txt
exit 0
Как вы, возможно, уже знаете, read перенаправляет файл на стандартный вход, который нумеруется 0. Вложенное чтение, используемое для запроса пользователя, наследует этот перенаправленный дескриптор файла. Это означает, что чтение с приглашением будет принимать ввод от 0, который теперь является не терминалом, а файлом.
Чтобы избежать этой проблемы, лучше перенаправить файл в дескриптор 3 и настроить внешнее чтение для использования дескриптора 3 в качестве входных данных.