Как заставить файл удара отзываться эхом по-другому на основе ввода данных пользователем?

Я являюсь довольно новым в сценариях оболочки, но я хотел бы записать основной сценарий, где файл удара повторит другую строку текста в зависимости от ввода данных пользователем. Например, если сценарий просит, чтобы пользователь "Был Вами там?" и ввод данных пользователем - "да" или "Да" затем, сценарий повторил бы что-то как "привет!". Но если бы ввод данных пользователем является "нет" или "Нет", сценарий повторил бы что-то еще. И наконец, если бы ввод данных пользователем - что-то другое, чем Да/Да или Нет/Нет, сценарий отозвался бы эхом, "Ответьте на да или не". Вот то, что я имею до сих пор:

echo "Are you there?"  
read $input  

if [ $input == $yes ]; then  
    echo "Hello!"  
elif [ $input == $no ]]; then  
    echo "Are you sure?"  
else  
    echo "Please answer yes or no."  
fi  

Однако, неважно, вход, я всегда получаю первый ответ ("Привет!")

Кроме того, я хотел бы включить текст к речи (поскольку я сделал с другими проектами файла удара с помощью фестиваля). В других файлах удара я сделал это этот путь:

echo "Hello!"  
echo "Hello!" | festival --tts

Существует ли способ включить это в если затем/да никакая подсказка выше? Заранее спасибо, я использую это, чтобы сделать простые файлы удара и помочь мне учиться.

8
задан 19 May 2018 в 23:20

3 ответа

Основная проблема здесь:

read $input

В ударе, обычно, $foo значение переменной foo. Здесь, Вы не хотите значение, но название переменной, таким образом, это должно быть справедливо:

read input

Точно так же в if тесты, $yes и $no должно быть справедливым yes и no, так как Вы просто хотите строки yes и no там.

Вы могли использовать a case оператор здесь, который (по моему скромному мнению), помогает сделать несколько случаев на основе входа:

case $input in
[Yy]es)    # The first character can be Y or y, so both Yes and yes work
    echo "Hello!"  
    echo "Hello!" | festival --tts
    ;;
[Nn]o)     # no or No
    echo "Are you sure?"
    echo "Are you sure?" | festival --tts
    ;;
*)         # Anything else
    echo "Please answer yes or no."
    echo "Please answer yes or no." | festival --tts
    ;;
esac

Вы могли перенести два echo операторы и использование festival в функции, чтобы не повторять себя:

textAndSpeech ()
{
    echo "$@"
    echo "$@" | festival --tts
}
case $input in
[Yy]es)    # The first character can be Y or y, so both Yes and yes work
    textAndSpeech "Hello!"  
    ;;
[Nn]o)     # no or No
    textAndSpeech "Are you sure?"
    ;;
*)         # Anything else
    textAndSpeech "Please answer yes or no."
    ;;
esac

С $input, колотите заменяет это его значением, которое является ничем первоначально, таким образом, read выполненная команда:

read 

И read значением по умолчанию хранит вход в переменной REPLY. Таким образом, если Вы хотите, можно устранить input переменная в целом и использование $REPLY вместо $input.


Также взгляните на select оператор в Bash.

13
ответ дан 23 November 2019 в 06:09

TL; DR: зафиксируйте синтаксические ошибки, удостоверьтесь, чтобы у Вас на самом деле были непустые переменные в [ тест, и делает функцию для передачи по каналу через tee в festival.

До печати для экранирования и вывод к festival, Я лично перенес бы сценарий в функцию и передал бы все по каналу к festival, с tee промежуточный (который отправляет текст и чтобы экранировать и передать по каналу).

Существует три проблемы синтаксиса для фиксации, однако:

  • read $input должен быть read input. $ символ разыменовывает переменную в сценариях оболочки (т.е. это $input будет заменен какой input содержит).
  • Вы имеете нет yes и no переменные объявляются. То, что необходимо делать, является сравнением строк: [ "$input" == "yes" ]
  • Дополнительный ]] в elif

Что касается того, почему Вы добираетесь Hello! все время это точно из-за первых двух пунктов маркированного списка. Прежде read $input переменная input не существует, таким образом, Вы только выполняете read (т.е. несуществующая переменная $input разыменовывается в пустую строку, уезжая только read управляйте там). Так независимо от того, что Вы вводите, хранится в REPLY переменная, которая является что read использование, когда никакое имя переменной не было дано. И потому что yes переменная не существует, который заменяется пустой строкой также. Таким образом в действительности [ $input == $yes ] рассматривается как [ "" == "" ] который всегда верен.

$ [ $nonexistent == $anothernonexistent  ] && echo "Success"
Success

Фиксированный сценарий должен быть как так:

#!/bin/bash
main(){
    read -p "Are you there?" input  

    if [ "$input" == "yes" ]; then  
        echo "Hello!"  
    elif [ "$input" == "no" ]; then  
        echo "Are you sure?"  
    else  
        echo "Please answer yes or no."  
    fi 
}
main | tee /dev/tty | festival --tts

Не забудьте заключать переменные в кавычки и читать на различии между = и == в тестовой команде.

14
ответ дан 23 November 2019 в 06:09

Третий подход должен был бы присвоить общей переменной для каждого случая, и в конце реагируют на ту переменную. Я не уверен, насколько распространенный этот подход находится в ударе, но на других языках программирования это довольно стандартно.

Также shopt -s nocasematch в сочетании с [[ для нечувствительного к регистру сравнения строк.
С этим также YES и NO рассматриваются как допустимый вход.

shopt
[[

#!/bin/bash

shopt -s nocasematch

read -p "Are you there?" input  

if [[ "$input" == "yes" ]]; then  
    msg="Hello!"  
elif [[ "$input" == "no" ]]; then  
    msg="Are you sure?"  
else  
    msg="Please answer yes or no."  
fi 

echo $msg
echo $msg | festival --tts
2
ответ дан 23 November 2019 в 06:09

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

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