我在shell脚本方面非常新,但我想编写一个基本脚本,bash文件将根据用户的输入回显不同的文本行。例如,如果脚本问用户“您在那里吗?”用户输入是“是”或“是”,那么脚本就会响应"hello!“之类的内容。但是,如果用户输入为"no“或"No”,则脚本将响应其他内容。最后,如果用户输入的内容不是“是/是”或“否”,脚本将响应“请回答是或否”。以下是我到目前为止所拥有的:
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
然而,不管输入,我总是得到第一个响应(“你好!”)
此外,我想把文本到演讲(就像我已经做了其他bash文件项目使用节日)。在其他bash文件中,我是这样做的:
echo "Hello!"
echo "Hello!" | festival --tts
是否有办法将其合并到上面的if然后/yes no提示符中?预先谢谢你,我用它来制作简单的bash文件,并帮助我自己学习。
发布于 2018-05-19 22:35:15
主要问题是:
read $input
在bash中,$foo
通常是变量foo
的值。在这里,您不需要值,而是变量的名称,所以它应该是:
read input
类似地,在if
测试中,$yes
和$no
应该只是yes
和no
,因为您只需要字符串yes
和no
。
您可以在这里使用一个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
,bash用它的值替换它,这在一开始并不是什么,所以read
命令运行如下:
read
默认情况下,read
将输入存储在变量REPLY
中。因此,如果需要,可以完全消除input
变量,使用$REPLY
而不是$input
。
还请看一看Bash中的这个select
语句。
发布于 2018-05-19 22:56:39
TL;DR:修复语法错误,确保[
测试中实际上有非空变量,并使一个函数通过tee
传输到festival
。
至于打印到屏幕上并输出到festival
,我会亲自将脚本包装成一个函数,并将所有内容输送到festival
,中间是tee
(将文本同时发送到屏幕和管道)。
但是,有三个语法问题需要修复:
read $input
应该是read input
。shell脚本中的$
符号取消变量(即,$input
将被input
所持有的内容所取代)。yes
和no
变量。您应该做的是字符串比较:[ "$input" == "yes" ]
]]
in 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
记得在引用变量上读间差=
和==
在测试命令中。
发布于 2018-05-20 13:46:22
第三种方法是为每种情况分配一个公共变量,最后对该变量采取行动。我不知道这种方法在bash中有多普遍,但在其他编程语言中它是相当标准的。
另外,shopt -s nocasematch
与[[
一起用于不区分大小写的字符串比较.同时,YES
和NO
也被作为有效输入处理。
商店 [[https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html ]
#!/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
https://askubuntu.com/questions/1038276
复制相似问题