если отрицательный или функция в Bash?

Я проверяю переменную для текущей строки:

check_string() { if [[ ! "$FILES" =~ "abcd" ]] || [[ ! "$FILES" =~ "xyz" ]]; then return 0 else return 1 fi } check_string 

Проблема в том, что второе условие [[ ! "$FILES" =~ "xyz" ]] [[ ! "$FILES" =~ "xyz" ]] никогда не оценивается.

Но когда я не отрицаю это, второе условие оценивается [[ "$FILES" =~ "xyz" ]] :

 check_string() { if [[ "$FILES" =~ "abcd" ]] || [[ "$FILES" =~ "xyz" ]]; then return 0 else return 1 fi } check_string 

Есть идеи ?

Если первое условие всегда выполняется, второе никогда не будет оцениваться.

Вы не упомянули содержание $FILES , но кажется, что $FILES никогда не похож на «abcd», и поэтому отрицание всегда верно.

Ваш тест

 [[ ! "$FILES" =~ "abcd" ]] || [[ ! "$FILES" =~ "xyz" ]] 

по закону де Моргана эквивалентно

 ! [[ "$FILES" =~ "abcd" && "$FILES" =~ "xyz" ]] 

Пока строка $FILES не соответствует обоим регулярным выражениям, тест всегда будет верным.

Обратите внимание, что ваша функция не должна явно возвращать единицу или ноль. Было бы достаточно с

 check_string() { [[ ! "$FILES" =~ "abcd" ]] || [[ ! "$FILES" =~ "xyz" ]] } 

Статус выхода функции будет соответствовать статусу последней выполненной команды в функции.


Если вы работаете со списком имен файлов или путей, не храните их в строке. Это помешает вашему скрипту работать с именами файлов, которые содержат пробелы. Вместо этого используйте правильный массив для хранения путей.

Я думаю, это логическое недоразумение. Было бы глупо, если бы вы сказали, что вы хотите сделать.

  1. вернуть 1, если один из определенных файлов отсутствует в списке?
  2. вернуть 1, если один или все определенные файлы отсутствуют в списке?
  3. вернуть 0, если один или определенный файл найден в списке?
  4. вернуть 0, если все определенные файлы найдены в списке?

Я мог бы сказать вам, что оба условия будут выполнены.

Если вы set -x в сценарии set -x , bash выведет вам то, что оценивается.

 $ cat check_string.sh #!/usr/bin/env bash set -x check_string() { if [[ ! "$FILES" =~ "abcd" ]] || [[ ! "$FILES" =~ "xyz" ]]; then return 0 else return 1 fi 

Вот мои чеки.

 $ FILES="abcd lmo xyz" ./check_string.sh + check_string + [[ ! abcd lmo xyz =~ abcd ]] + [[ ! abcd lmo xyz =~ xyz ]] + return 1 $ FILES="abcd lmo" ./check_string.sh + check_string + [[ ! abcd lmo =~ abcd ]] + [[ ! abcd lmo =~ xyz ]] + return 0 $ FILES="lmo xyz" ./check_string.sh + check_string + [[ ! lmo xyz =~ abcd ]] + return 0 $ FILES="abcd" ./check_string.sh + check_string + [[ ! abcd =~ abcd ]] + [[ ! abcd =~ xyz ]] + return 0 $ FILES="lmo" ./check_string.sh + check_string + [[ ! lmo =~ abcd ]] + return 0 $ FILES="xyz" ./check_string.sh + check_string + [[ ! xyz =~ abcd ]] + return 0 } check_string 

Кроме того: На мой взгляд, условия могут быть написаны немного более ясно. + Изменить

 if [[ ! "$FILES" =~ "abcd" ]] || [[ ! "$FILES" =~ "xyz" ]]; 

в

 if [[ ! "$FILES" =~ "abcd" || ! "$FILES" =~ "xyz" ]]; 

Альтернативная реализация (не специфичная для bash)

 check_string() { case "$1" in *abcd*|*xyz*) return 1 ;; *) return 0 esac } check_string "$FILES"