Я пытаюсь создать вложенный оператор case, в котором ожидается ввод данных пользователем (Y / N). Однако система никогда не ждет ввода и всегда переходит к третьему варианту: «Пожалуйста, ответьте да или нет». Может кто-нибудь сказать мне, что я пропускаю?
Вот пример случая
#!/bin/bash
STATUS=status
find /etc/init.d/* -name '*' -print0 | while IFS= read -r -d '' FILE;
do
if [ "$FILE" != "." -o "$FILE" != ".." ]; then
OUTPUT=$($FILE $STATUS)
case "$OUTPUT" in
*disabled* )
echo "Do you wish to start $FILE ?"
read yn
case $yn in
[yY] | [yY][Ee][Ss] )
$FILE start
;;
[nN] | [n|N][O|o] )
;;
* )
echo "Please answer yes or no.";;
esac
;;
* )
echo "App $FILE is running"
;;
esac
fi
done
Запуск под Ubuntu 14.04 LTS
Пример вывода
App /etc/init.d/reboot is running
App /etc/init.d/resolvconf is running
App /etc/init.d/rsync is running
App /etc/init.d/rsyslog is running
App /etc/init.d/samba is running
App /etc/init.d/samba-ad-dc is running
Do you wish to start /etc/init.d/saned ?
Please answer yes or no.
Вы передаете по каналу find
вывод к циклу с условием продолжения. Внутренняя команда чтения читает строку от find
вывод, не от stdin.
можно реструктурировать как это: отправьте эти find
вывод к циклу с условием продолжения на различном дескрипторе файла. Это оставляет stdin свободный для внутреннего чтения.
while IFS= read -u3 -r -d '' FILE; do
if [ "$FILE" != "." -o "$FILE" != ".." ]; then
OUTPUT=$($FILE $STATUS)
case "$OUTPUT" in
*disabled* )
read -p "Do you wish to start $FILE ?" yn
case $yn in
[yY] | [yY][Ee][Ss] ) $FILE start ;;
[nN] | [nN][Oo] ) ;;
* ) echo "Please answer yes or no.";;
esac
;;
* ) echo "App $FILE is running" ;;
esac
fi
done 3< <(find /etc/init.d/* -name '*' -print0)
Это использует замена процесса , вместо канала, для чтения от find
Контекст на этот раз предоставляет ответ. Вы передаете вывод по каналу находки в весь цикл с условием продолжения, и это включает Ваше внутреннее чтение также... значение, Ваше "чтение yn" будет также читать из того же самого вывода, которые "находят", обеспечивает, в противоположность с Вашей клавиатуры.
мне также не нравится Ваша общая обработка цикличного выполнения по файлам. Простое:
for file in /etc/init.d/*; do
echo Processing $file
done
обычно работы хорошо в наше время, даже для больших сумм файлов.
, Если действительно необходимо использовать, находят, Вы могли бы, возможно, обернуть свой обработчик в другом сценарии и назвать его для каждого файла с:
find /etc/init.d -type f -perm +111 -exec myhandlerscript.sh {} \;
Это найдет все файлы с исполняемыми полномочиями и назовет myhandlerscript.sh для каждого с именем как аргумент. В сценарии имя файла появится в специальной переменной за 1$.
, Если это действительно должно быть в том же файле, оберните код в функции, экспортируйте его с "экспортом-f myfunction" и использованием "-исполнительный удар-c 'myfunction "0$"' {} \"; в качестве параметра найти.
Ваше использование команды "чтения", кажется, не совершенно правильно.
read -p "Do you wish to input data ?" yn
переключатель-p ожидает строку прямо рядом с ним, которая будет использоваться в качестве Подсказки. Таким образом это думало, что "yn" был чем-то для отображения, а не переменная для хранения ответа в.