Szukaj…


Składnia

  • [[-OP $ nazwa pliku]]
  • [[$ plik1 -OP $ plik2]]
  • [[-z $ string]]
  • [[-n $ ciąg]]
  • [["$ string1" == "$ string2"]]
  • [["$ string1" == $ wzorzec]]

Uwagi

Składnia [[ … ]] otacza wbudowane wyrażenia warunkowe bash. Zauważ, że wymagane są spacje po obu stronach nawiasów.

Wyrażenia warunkowe mogą używać jednoargumentowych i binarnych operatorów do testowania właściwości ciągów, liczb całkowitych i plików. Mogą również korzystać z operatorów logicznych && , || i ! .

Porównanie plików

if [[ $file1 -ef $file2 ]]; then
  echo "$file1 and $file2 are the same file"
fi

„Ten sam plik” oznacza, że modyfikacja jednego z plików na miejscu wpływa na drugi. Dwa pliki mogą być takie same, nawet jeśli mają różne nazwy, na przykład jeśli są dowiązaniami stałymi lub jeśli są dowiązaniami symbolicznymi z tym samym celem lub jeśli jeden jest dowiązaniem symbolicznym skierowanym do drugiego.

Jeśli dwa pliki mają tę samą zawartość, ale są odrębnymi plikami (tak, że modyfikowanie jednego nie wpływa na drugi), to -ef zgłasza je jako różne. Jeśli chcesz porównać dwa pliki bajt po bajcie, użyj narzędzia cmp .

if cmp -s -- "$file1" "$file2"; then
  echo "$file1 and $file2 have identical contents"
else
  echo "$file1 and $file2 differ"
fi

Aby utworzyć czytelną dla człowieka listę różnic między plikami tekstowymi, użyj narzędzia diff .

if diff -u "$file1" "$file2"; then
  echo "$file1 and $file2 have identical contents"
else
  : # the differences between the files have been listed
fi

Testy dostępu do plików

if [[ -r $filename ]]; then
  echo "$filename is a readable file"
fi
if [[ -w $filename ]]; then
  echo "$filename is a writable file"
fi
if [[ -x $filename ]]; then
  echo "$filename is an executable file"
fi

Testy te uwzględniają uprawnienia i własność w celu ustalenia, czy skrypt (lub programy uruchomione ze skryptu) może uzyskać dostęp do pliku.

Uwaga na warunki wyścigu (TOCTOU) : fakt, że test się teraz powiedzie, nie oznacza, że nadal obowiązuje on w następnym wierszu. Zwykle lepiej jest spróbować uzyskać dostęp do pliku i poradzić sobie z błędem, niż najpierw przetestować, a następnie i tak poradzić sobie z błędem, jeśli plik w międzyczasie się zmienił.

Porównania numeryczne

W porównaniach numerycznych używamy operatorów -eq i przyjaciół

if [[ $num1 -eq $num2 ]]; then
  echo "$num1 == $num2"
fi
if [[ $num1 -le $num2 ]]; then
  echo "$num1 <= $num2"
fi

Istnieje sześć operatorów numerycznych:

  • -eq równe
  • -ne jest równy
  • -le mniejszy lub równy
  • -lt mniej niż
  • -ge większy lub równy
  • -gt większy niż

Zauważ, że operatory < i > wewnątrz [[ … ]] porównują ciągi, a nie liczby.

if [[ 9 -lt 10 ]]; then
  echo "9 is before 10 in numeric order"
fi
if [[ 9 > 10 ]]; then
  echo "9 is after 10 in lexicographic order"
fi

Dwie strony muszą być liczbami zapisanymi dziesiętnie (lub ósemkowo z wiodącym zerem). Alternatywnie można użyć składni wyrażeń arytmetycznych ((…)) , która wykonuje obliczenia liczb całkowitych w składni podobnej do C / Java /…

x=2
if ((2*x == 4)); then
  echo "2 times 2 is 4"
fi
((x += 1))
echo "2 plus 1 is $x"

Porównanie i dopasowanie ciągów

Porównanie ciągów używa operatora == pomiędzy ciągami cytowanymi . Operator != Neguje porównanie.

if [[ "$string1" == "$string2" ]]; then
  echo "\$string1 and \$string2 are identical"
fi
if [[ "$string1" != "$string2" ]]; then
  echo "\$string1 and \$string2 are not identical"
fi

Jeśli prawa strona nie jest cytowana, to jest to wzór wieloznaczny, z którym dopasowany jest $string1 .

string='abc'
pattern1='a*'
pattern2='x*'
if [[ "$string" == $pattern1 ]]; then
  # the test is true
  echo "The string $string matches the pattern $pattern"
fi
if [[ "$string" != $pattern2 ]]; then
  # the test is false
  echo "The string $string does not match the pattern $pattern"
fi

Operatory < i > porównują ciągi w porządku leksykograficznym (dla ciągów nie ma mniejszych lub równych lub większych lub równych operatorów).

Istnieją pojedyncze testy dla pustego łańcucha.

if [[ -n "$string" ]]; then
  echo "$string is non-empty"
fi
if [[ -z "${string// }" ]]; then
  echo "$string is empty or contains only spaces"
fi
if [[ -z "$string" ]]; then
  echo "$string is empty"
fi

Powyżej, -z może oznaczać, że $string jest nieustawiony lub jest ustawiony na pusty ciąg. Aby rozróżnić puste i nieuzbrojone, użyj:

if [[ -n "${string+x}" ]]; then
    echo "$string is set, possibly to the empty string"
fi
if [[ -n "${string-x}" ]]; then
    echo "$string is either unset or set to a non-empty string"
fi
if [[ -z "${string+x}" ]]; then
    echo "$string is unset"
fi
if [[ -z "${string-x}" ]]; then
    echo "$string is set to an empty string"
fi

gdzie x jest dowolne. Lub w formie tabeli :

                        +-------+-------+-----------+
            $string is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [[ -z ${string} ]]    | true  | true  | false     |
| [[ -z ${string+x} ]]  | true  | false | false     |
| [[ -z ${string-x} ]]  | false | true  | false     |
| [[ -n ${string} ]]    | false | false | true      |
| [[ -n ${string+x} ]]  | false | true  | true      |
| [[ -n ${string-x} ]]  | true  | false | true      |
+-----------------------+-------+-------+-----------+

Alternatywnie , stan można sprawdzić w instrukcji case:

case ${var+x$var} in
  (x) echo empty;;
  ("") echo unset;;
  (x*[![:blank:]]*) echo non-blank;;
  (*) echo blank
esac

Gdzie [:blank:] to specyficzne dla ustawień regionalnych poziome odstępy (tabulator, spacja itp.).

Testy typu pliku

Operator warunkowy -e sprawdza, czy plik istnieje (w tym wszystkie typy plików: katalogi itp.).

if [[ -e $filename ]]; then
  echo "$filename exists"
fi

Istnieją również testy dla określonych typów plików.

if [[ -f $filename ]]; then
  echo "$filename is a regular file"
elif [[ -d $filename ]]; then
  echo "$filename is a directory"
elif [[ -p $filename ]]; then
  echo "$filename is a named pipe"
elif [[ -S $filename ]]; then
  echo "$filename is a named socket"
elif [[ -b $filename ]]; then
  echo "$filename is a block device"
elif [[ -c $filename ]]; then
  echo "$filename is a character device"
fi
if [[ -L $filename ]]; then
  echo "$filename is a symbolic link (to any file type)"
fi

W przypadku dowiązania symbolicznego oprócz -L testy te dotyczą celu i zwracają wartość false dla zerwanego łącza.

if [[ -L $filename || -e $filename ]]; then
  echo "$filename exists (but may be a broken symbolic link)"
fi

if [[ -L $filename && ! -e $filename ]]; then
  echo "$filename is a broken symbolic link"
fi

Testuj status wyjścia polecenia

Wyjdź ze stanu 0: sukces
Status wyjścia inny niż 0: błąd

Aby przetestować status wyjścia polecenia:

if command;then
    echo 'success'
else
    echo 'failure'
fi

Test jednej wkładki

Możesz robić takie rzeczy:

[[ $s = 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s == 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s != 'something' ]] && echo "didn't match" || echo "matched"
[[ $s -eq 10 ]] && echo 'equal' || echo "not equal"
(( $s == 10 )) && echo 'equal' || echo 'not equal'

Jeden test liniowy dla statusu wyjścia:

command && echo 'exited with 0' || echo 'non 0 exit'
cmd && cmd1 && echo 'previous cmds were successful' || echo 'one of them failed'
cmd || cmd1 #If cmd fails try cmd1


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow