2017-02-23 69 views
2
没有用户输入的

我的bash脚本应该接受用户的输入,处理与特定文件退出,如:使得bash脚本退出如果在标准输入

if [ -e "formatted_log.csv" ] 
then 
    printf "\nPresence of formatted_log.csv file detected: It appears this script has already been run is this dir.\n" 
    printf "Appending can cause errors.\n" 
    read -e -p "Would you like to continue?[y/n]" stdin 

这种逻辑检查用户输入:

if [ $stdin = "n" ] || [ $stdin = "N" ]; 
then 
printf "\nOkay, exiting.\n" 
exit; 
fi 
if [ $stdin != "y" ]&&[ $stdin != "Y" ]&&[ $stdin != "n" ]&&[ $stdin != "N" ]; 
then 
printf "\nPlease use a valid input (y/n)...exiting.\n" 
exit; 
    fi 
fi 

问题是,如果你只是按下输入脚本执行,就好像一个“Y”或“Y”已被输入,我不知道为什么。我的理解是,这是书面的方式,它应该如果用户将在比唉,Y以外的任何时候你有没有输入退出,n或N.

它打印此:

master_script.sh: line 14: [: =: unary operator expected 
master_script.sh: line 14: [: =: unary operator expected 
master_script.sh: line 19: [: !=: unary operator expected 

但不退出–我该如何退出?

+0

切换到[[]]'形式的[条件表达式](http://wiki.bash-hackers.org/syntax/ccmd/conditional_expression)可能会让你快速浏览。还要确保每个'''''''&&''||'等都有空格。 [shellcheck](http://shellcheck.net)可以帮助你。 – cxw

+0

如果你只是要退出,就告诉用户他们输入了一个无效的输入信息是没有意义的(就好像他们输入'n'或'N')。 – chepner

+1

'test -f'不*检查存在 - 它比这更挑剔。你需要写'-e'或者改变你的描述。 –

回答

3

由于您用“Bash”标记了此标签,因此您应该拥有功能更强大的[[ ]]操作员。然后,您可以简化为这样的事情:

read stdin 

if [[ $stdin == [Nn] ]]; then 
    echo "Exiting" 
    exit 
fi 

if [[ $stdin != [YyNn] ]]; then 
    echo "Invalid input, exiting" 
    exit 
fi 

==(或=)和[[ ]]!=执行模式匹配,所以你可以使用模式来检查,如果您的输入是有效的,在像[YyNn]一个表达式。

如果你要问的输入,直到用户输入了一些有效的,你可以循环是这样的:

while [[ $stdin != [YyNn] ]]; do 
    read -p 'Continue? ' stdin 
done 

注意的是,虽然它几乎总是好的做法,引用Bash中的变量,你不必须在[[ ]]之内。如果你的模式是在一个变量,它实际上一定不能被引用,或者它不被解释为模式。

+0

感谢您使用模式匹配的额外提示! – 5r9n

2

问题是NOT具有不具有空值保留时引号不存在可变$stdin周围的报价,

例如,[...]看到表达式作为当变量是空的下面,

+ '[' = n ']' 
script.sh: line 9: [: =: unary operator expected 
+ '[' = N ']' 
script.sh: line 9: [: =: unary operator expected 
+ '[' '!=' y ']' 
script.sh: line 14: [: !=: unary operator expected 
+ '[' 0 eq 0 ']' 

您需要正确地引用他们,使其工作,本着

9 if [ "$stdin" = "n" ] || [ "$stdin" = "N" ]; 

14 if [ "$stdin" != "y" ] && [ "$stdin" != "Y" ] && [ "$stdin" != "n" ] && [ "$stdin" != "N" ]; 

与此相关,输入按键的安全处理,

+ '[' '' = n ']' 
+ '[' '' = N ']' 
+ '[' '' '!=' y ']' 
+ '[' '' '!=' Y ']' 
+ '[' '' '!=' n ']' 
+ '[' '' '!=' N ']' 

与运行完整的脚本,然后按在提示符下输入,在调试模式下的上述变化,

bash -x script.sh 
+ '[' -f file ']' 
+ printf '\nPresence of formatted_log.csv file detected: It appears this script has already been run is this dir.\n' 

Presence of formatted_log.csv file detected: It appears this script has already been run is this dir. 
+ printf 'Appending can cause errors.\n' 
Appending can cause errors. 
+ read -e -p 'Would you like to continue?[y/n]' stdin 
Would you like to continue?[y/n] 
+ '[' '' = n ']' 
+ '[' '' = N ']' 
+ '[' '' '!=' y ']' 
+ '[' '' '!=' Y ']' 
+ '[' '' '!=' n ']' 
+ '[' '' '!=' N ']' 
+ printf '\nPlease use a valid input (y/n)...exiting.\n' 

Please use a valid input (y/n)...exiting. 
+ exit 

作为一个健康的替代,你可以只使用负正则表达式匹配允许提示的名单如下

if [[ ! $stdin =~ ^(y|Y|n|N)$ ]] 

另一种有效的方法,只是检查的变量只是一个空字符串,

if [ "$stdin" = "" ]