如何根据用户输入让 bash 文件以不同方式回显?

San*_*ago 8 command-line bash scripts

我对 shell 脚本很陌生,但我想编写一个基本脚本,其中 bash 文件将根据用户输入回显不同的文本行。例如,如果脚本询问用户“你在那里吗?” 并且用户输入是“是”或“是”,那么脚本会回显类似“你好!”的内容。但是如果用户输入是“否”或“否”,脚本会回显其他内容。最后,如果用户输入不是是/是或否/否,脚本将回显“请回答是或否”。这是我到目前为止所拥有的:

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  
Run Code Online (Sandbox Code Playgroud)

但是,无论输入如何,我总是得到第一个响应(“您好!”)

另外,我想将文本合并到语音中(就像我使用节日对其他 bash 文件项目所做的那样)。在其他 bash 文件中,我是这样做的:

echo "Hello!"  
echo "Hello!" | festival --tts
Run Code Online (Sandbox Code Playgroud)

有没有办法将其合并到上面的 if then/yes no 提示中?在此先感谢您,我正在使用它来制作简单的 bash 文件并帮助自己学习。

Olo*_*rin 14

主要问题在这里:

read $input
Run Code Online (Sandbox Code Playgroud)

在 bash 中,通常$foo是变量的值foo。在这里,您不需要值,而是变量的名称,所以它应该只是:

read input
Run Code Online (Sandbox Code Playgroud)

同样,在if测试中,$yesand$no应该只是yesand no,因为你只想要字符串yesno那里。

您可以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
Run Code Online (Sandbox Code Playgroud)

您可以将这两个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
Run Code Online (Sandbox Code Playgroud)

使用$input,bash 用它的值替换它,它最初是什么,所以read命令运行是:

read 
Run Code Online (Sandbox Code Playgroud)

read默认存储在变量输入REPLY。因此,如果需要,您可以input完全消除变量并使用$REPLY代替$input


另请查看Bash中select语句


Ser*_*nyy 14

TL;DR:修复语法错误,确保您在[测试中确实有非空变量,并制作一个函数以通过管道tee进入festival.

至于打印到屏幕和输出到festival,我个人会将脚本包装成一个函数并将所有内容通过管道传输到festivaltee两者之间(将文本同时发送到屏幕和管道)。

但是,有三个语法问题需要解决:

  • read $input应该是read input。将$在shell脚本符号解引用变量(即,它$input会用什么来代替input持有)。
  • 你没有声明yesno变量。你应该做的是字符串比较:[ "$input" == "yes" ]
  • 额外]]elif

至于为什么你总是得到Hello!,那正是因为前两个要点。在read $input变量input不存在之前,所以你只是在执行read(即,不存在的变量$input被取消引用为空字符串,只留下read命令)。因此,您键入的任何内容都会存储在REPLY变量中,该变量read在未给出变量名称时使用。并且因为yes变量不存在,它也被替换为空字符串。因此在现实中[ $input == $yes ]被视为[ "" == "" ]总是正确的。

$ [ $nonexistent == $anothernonexistent  ] && echo "Success"
Success
Run Code Online (Sandbox Code Playgroud)

固定脚本应该是这样的:

$ [ $nonexistent == $anothernonexistent  ] && echo "Success"
Success
Run Code Online (Sandbox Code Playgroud)

请记住引用变量并阅读test command之间的差异===