2015-10-04 22 views
5

Buduję skrypt, który wykona kopię zapasową bazy danych WordPress. I stworzyły potrzebę funkcji dla zrzutu MySQL:Bash: Nie można wejść, nawet jeśli warunek jest prawdziwy

function db_backup { 
    read -r -p "Dump the database? [Y/n]: " response 
    if [[ $response =~ ^([yY][eE][sS] || [yY])$ ]] 
    then 
     mysqldump -h $1 -u $2 -p$3 $4 > $4.sql 

     if [[ $? == 0 ]] 
     then 
      printf "Database %s dumped successfuly in %s.sql\n" ${db_name} ${db_name} 
      return 0 
     else 
      printf "Database backup %bfailed%b\n" ${red} ${reset} 
      return 1 
     fi 
    else 
     return 1 
    fi 
} 

Gdy Y lub Tak/Tak/Tak/Tak/Tak jest napastnikiem - to nie wchodzi w razie prawdziwego bloku, a nie zrzut tworzony jest: (dane bazy danych są poprawne i zrzut idzie na rękę, ale nie jestem w stanie wejść w warunku IF

+1

Wpisz cudzysłowie regexp, np: '[[$ response = ~„^ ([RR] [EE] [SS] || [YY ]) $ "]]' – edi9999

+2

Wyrecytowane zostanie dopasowane (nie uwzględniające wielkości liter cudzysłowy dodane do celów formatowania) '" tak "' (ze spacją końcową) lub '" y "' (z spacją wiodącą) lub pusty ciąg znaków '' "' ... czy tego chcesz? –

Odpowiedz

5

Spróbuj użyć case oświadczenie:.

db_backup() 
{ 
    read -r -p "Dump the database? [Y/n]: " response 

    case "$response" in 
    y|Y|yes|Yes|YES) 
     mysqldump -h $1 -u $2 -p$3 $4 > $4.sql 

     if [[ $? == 0 ]] 
     then 
      printf "Database %s dumpedy in %s.sql\n" ${db_name} ${db_name} 
      return 0 
     else 
      printf "Database backup %bfailed%b\n" ${red} ${reset} 
      return 1 
     fi 
     ;; 
    esac 
    return 1 

} 
+2

'shopt -s noceleatch' może być również użyteczny tutaj. –

+0

Twoje rozwiązanie wykonało zadanie! Podziękowania dla innych, którzy również wzięli udział w moim pytaniu! –

3

Twoje pasuje do wyrażenia regularnego (case-insensitive- dodano cudzysłowy do celów formatowania) "yes " (z końcowym odstępem) lub " y" (ze spacją wiodącą) lub pustym ciągiem "" .

Zapis ten zamiast:

if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]] 

lub nawet lepiej

if [[ $response =~ ^[yY]([eE][sS])?$ ]] 

Można również użyć globs:

if [[ $response = [yY]?([eE][sS]) ]] 

(z Basha < 4.1 trzeba shopt -s extglob). Można również konwertować response do małymi literami:

if [[ ${response,,} = y?(es) ]] 

(ekspansja ${var,,} parametr pojawił się w Bash 4.0).


i najśmieszniejsze jest to, że read (z domyślnym IFS) paski początkowe i końcowe spacje ... więc, że to niemożliwe, aby mieć mecz z niepustym ciągiem.

0

Dlaczego nie przekształcić odpowiedzi na wszystkie czapki, potem porównać do Y lub Tak, na przykład, zrobić:

if [[ ${response^^} =~ ^(Y|YES)$ ]]; then ... fi

Ma to tę zaletę, że nie trzeba myśleć o możliwych kombinacje wielkich/małych liter, wszystkie są wykrywane. Ponadto, zamiast:

if [[ $? == 0 ]]; then ... fi

Można po prostu zrobić:

if [[ $? ]]; then ... fi

Dla testów prawdę, rezultatem [[ 0 ]] jest prawdziwe, natomiast wynik ((0)) jest fałszywe.

Rozważmy pewne uproszczenia, dla czytelności, takie jak

function db_backup { 
    read -r -p "Dump the database? [Y/n]: " response 
    if [[ ${response^^} =~ ^(Y|YES)$ ]] 
    then 
     if mysqldump -h $1 -u $2 -p$3 $4 > $4.sql 
     then 
      printf "Database %s dumped successfuly in %s.sql\n" ${db_name} ${db_name} 
      return 0 
     else 
      printf "Database backup %bfailed%b\n" ${red} ${reset} 
      return 1 
     fi 
    else 
     return 1 
    fi 
} 
+1

@gniourf_gniourf: regex zakotwiczone, zgodnie z zaleceniami, dzięki. – AsymLabs

Powiązane problemy