Скрипт, пропускающий пользовательский ввод в вложенном регистре

Я пытаюсь создать вложенный оператор 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.
1
задан 26 June 2014 в 16:44

3 ответа

Вы передаете по каналу 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

3
ответ дан 26 June 2014 в 16:44

Контекст на этот раз предоставляет ответ. Вы передаете вывод по каналу находки в весь цикл с условием продолжения, и это включает Ваше внутреннее чтение также... значение, Ваше "чтение 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$"' {} \"; в качестве параметра найти.

2
ответ дан 26 June 2014 в 16:44

Ваше использование команды "чтения", кажется, не совершенно правильно.

read -p "Do you wish to input data ?" yn

переключатель-p ожидает строку прямо рядом с ним, которая будет использоваться в качестве Подсказки. Таким образом это думало, что "yn" был чем-то для отображения, а не переменная для хранения ответа в.

1
ответ дан 26 June 2014 в 16:44

Другие вопросы по тегам:

Похожие вопросы: