2017-02-23 66 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" = "" ]