Логічний І в сценарії bash


10

У мене є ifсценарій bash, який повинен перевірити, чи існує EITHER з 2-х файлів, якщо вони не існують, він повинен відповідати.

Код у мене:

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

Але це, здається, не працює чомусь.

Я на 110% впевнений, що ці 2 файли не існують. Я не отримую жодних помилок, він просто не вводиться if.

Я новачок у сценаріїх, коли я не знаю, що може бути не так.


Я не думаю, що жодна з опублікованих відповідей насправді не стосується цього питання. Що відбувається, коли ви пробуєте тести індивідуально? Зробіть [[ ! -f /etc/.../... ]]; echo $?для кожного.
jw013

Попередження : [[ -f xxx ]]повертає істину, якщо існує xxx і є звичайним файлом (або символьним посиланням на звичайний файл). Він поверне помилковим, якщо його не існує, або якщо він не може визначити, існує чи ні, чи існує, але це не звичайний файл (каталог, труба, пристрій, сокет ...) або якщо це посилання до файлу, який не існує, або він не може визначити, існує він чи ні, чи це не звичайний файл ... [[ -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оцінюється ваше твердження, запустіть його -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

У такому випадку ваш оригінальний код повинен бути добре. І справді це працює для мене.
bahamat

3

Чи не повинно бути так? A - файл або B - файл, потім blabla.

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.
hschou

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.