2014-01-16 58 views
21

我有下面這段bashscript的:bash的字符串比較多正確的價值觀

function get_cms { 
    echo "input cms name" 
    read cms 
    cms=${cms,,} 
    if [ "$cms" != "wordpress" && "$cms" != "meganto" && "$cms" != "typo3" ]; then 
     get_cms 
    fi 
} 

但無論怎樣我輸入(正確和不正確的值),它永遠不會再次調用該函數,因爲我只希望允許這3個輸入中的1個。 我已經用||嘗試過了[var!= value]或[var!= value1]或[var!= value1] ,但沒有任何效果。 有人能指引我正確的方向嗎?

+0

的可能重複[Bash的if語句來檢查。如果字符串等於一個幾個字符串文字](http://stackoverflow.com/questions/22259259/bash-if-statement-to-check-if-string-is-equal-to-one-of-several-string-literals) –

回答

21

不要說:

if [ "$cms" != "wordpress" && "$cms" != "meganto" && "$cms" != "typo3" ]; then 

說:

if [[ "$cms" != "wordpress" && "$cms" != "meganto" && "$cms" != "typo3" ]]; then 

您可能還需要參考Conditional Constructs

+0

那作品。我怎麼會錯過這個? – eagle00789

+0

重複'「$ cms」!='又一次不是非常乾燥。在任何情況下(例如'「csm」!='),都會留下錯字的空間,而且你沒有編譯器可以在shell中指出這一點。最好儘量避免重複變量名稱。 (請參閱我的答案,以達到這個目的。) – Alfe

24

也許你應該更好地使用case這樣的名單:

case "$cms" in 
    wordpress|meganto|typo3) 
    do_your_else_case 
    ;; 
    *) 
    do_your_then_case 
    ;; 
esac 

我覺得長期這樣的名單,這是更好的可讀性。

如果你還是喜歡if您可以通過兩種方式與單括號做到這一點:

if [ "$cms" != wordpress -a "$cms" != meganto -a "$cms" != typo3 ]; then 

if [ "$cms" != wordpress ] && [ "$cms" != meganto ] && [ "$cms" != typo3 ]; then 
+1

它很棒!順便說一句,沒有「do_your_then | else_case」文字提示倒置? :) –

+1

OP正在使用≠('!=')來表達他的原始狀態;我的版本與'case'是匹配的(所以它使用與'='的比較),因此是反轉。 – Alfe

+1

美麗的解決方案。是否有任何與使用這種情況相關的陷阱? – Xiao

2

這裏是我的解決方案

if [[ "${cms}" != +(wordpress|magento|typo3) ]]; then 
+3

你的extglob中不是'+'而是'@'。否則,你會得到錯誤的結果,例如'wordpressmagento'或'typo3typo3'。 –

29

如果主要意圖是檢查提供的值是否沒有在列表中找到,也許你可以使用分機截至正則表達式匹配通過「平等波浪」操作符建於BASH(見this answer):

if ! [[ "$cms" =~ ^(wordpress|meganto|typo3)$ ]]; then get_cms ; fi 

有一個愉快的一天