Логическое И в скрипте bash


10

У меня есть ifв моем скрипте bash, который должен проверить, существует ли ЛИБО из 2 файлов, если они не существуют, он должен совпадать.

Код у меня есть:

if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Но это, похоже, не работает по какой-то причине.

Я на 110% уверен, что эти 2 файла не существуют. Я не получаю никаких ошибок, он просто не входит if.

Я новичок в сценарии Bash, поэтому я не уверен, что может быть не так.


Я не думаю, что какой-либо из опубликованных ответов на самом деле касается вопроса. Что происходит, когда вы тестируете тесты индивидуально? Сделать [[ ! -f /etc/.../... ]]; echo $?для каждого.
jw013

Предупреждение : [[ -f xxx ]]возвращает true, если xxx существует и является обычным файлом (или символической ссылкой на обычный файл). Он вернет false, если он не существует, или если он не может сказать, существует ли он или нет, или если он существует, но не является обычным файлом (каталог, канал, устройство, сокет ...) или если это символическая ссылка к файлу, который не существует, или он не может определить, существует он или нет, или не является обычным файлом ... [[ -e $file ]] || [[ -L $file ]]ближе к тесту на существование. ls -d -- "$file" > /dev/null 2>&1еще ближе. И, как правило, этот вид испытаний приводит к условиям гонки. Может быть, есть другой способ.
Стефан Шазелас

Ответы:


12

Если вы хотите , либо , то вы хотите OR, а не AND.

if [[ ! -f /etc/benchmarking/code ]] || [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
  • Это будет соответствовать, если один или оба файла отсутствуют.
  • Ваш код будет напечатан, только matchесли оба не существуют.

Но вы сказали:

Я на 110% уверен, что эти 2 файла не существуют. Я не получаю никаких ошибок, он просто не входит в if.

Так что ваше утверждение противоречит само себе. По крайней мере, один из этих файлов должен существовать, если вы запускаете этот код.

Если вы хотите увидеть, как ifоценивает ваше утверждение, запустите его с -x.

#!/bin/bash -x
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Тогда ты увидишь казнь.

$ ./test.sh
+ [[ ! -f /etc/benchmarking/code ]]
+ [[ ! -f /etc/benchmarking/code.class ]]
+ echo match
match
$ 

Я хочу, чтобы он отображал «совпадение», если ни один файл не существует, если он существует, он не печатает совпадение. Я попробую это с -x
Peppercat101

В этом случае ваш оригинальный код должен быть в порядке. И действительно, это работает для меня.
Багамат

3

Разве это не должно быть так? А это файл или Б это файл, тогда блабла.

if [[ -f /etc/benchmarking/code ]] || [[ -f /etc/benchmarking/code.class ]]; 
then  
  echo "match"
fi

3

Это также может работать на то, что вы пытаетесь сделать. Одиночные скобки обычно не используются сегодня с bash, но это все еще вариант. Использование '-o' фактически является операцией "ИЛИ", а "!" отрицает условие.

var=/etc/benchmarking/code
[ ! -f ${var} -o -f {var}.class ] && echo "match"

Никогда не используйте [в bash. Кроме того, я не вижу, как это отвечает на вопрос.
jw013

[ ! -f ${var} -a ! -f {var}.class ] && echo "match"должен быть. Задание было: если они (оба) не существуют, это должно быть echo match.
16:15

0

Ваш код удовлетворяет вашим требованиям: он будет печататься matchпри условии, что не может найти ни один файл.

Поэтому причина matchне печатается в другом месте. Вы должны подтвердить, что блок кода достигнут, что вы можете сделать, окружив его парой отладочных сообщений. Например, вот так:

echo '@ About to enter if...fi block'
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
echo '@ Finished if...fi block'

Обычно я предпочитаю, чтобы сообщения отладки отправлялись в stderr, чтобы не прерывать поток данных в stdout , но я избегал этого здесь, потому что вы сказали, что вы новичок. Вот один пример, показывающий, как вы можете написать в stdout :

echo '@ About to enter if...fi block' >&2
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.