2014-01-16 6 views
21

у меня есть следующий фрагмент bashscript:Баш строка сравнить с несколькими правильными значениями

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

Но независимо от того, что я ввода (правильные и неправильные значения) он никогда не вызывает функцию, потому что я только хочу, чтобы 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 "! ='), И у вас нет компилятора, чтобы указать на него в оболочках. Лучше попробуйте избежать повторения имени переменной. (См. Мой ответ, чтобы сделать это.) – 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

он отлично работает! btw, arent «do_your_then | else_case» текст перевернут? :) –

+1

ОП формулировал свое исходное состояние с помощью ≠ ('! ='); моя версия с 'case' является совпадением (поэтому она скорее использует сравнение с' = '), следовательно, инверсия. – Alfe

+1

Красивое решение. Есть ли какие-либо ошибки, связанные с использованием такого случая? – Xiao

2

Вот мое решение

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

Не '+', а '@' в вашем extglob. В противном случае вы получите неправильные результаты, например, 'wordpressmagento' или' typo3typo3'. –

29

Если главная цель заключается в том, чтобы проверить, не указано ли входящее значение в списке, возможно, вы можете использовать ext закончились регулярные выражения, построенные в BASH через «равную тильду» оператор (см также this answer):

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

имеет хороший день

Смежные вопросы