2016-06-28 1 views
0

Этот вопрос отличается от множества возможных дубликатов, и я не смог найти ответ на этот вопрос или даже спросил ...Множественные И условия в bash, которые работают независимо на основе разделителя условий ИЛИ?

Может быть, я пропустил простую логику здесь, но я столкнувшись с проблемой:

Я пытаюсь получить заявление if, где должны быть выполнены условия, например $V1 И $V2 ИСТИННЫЕ || ИЛИ $V3 И $V4 ИСТИНЫ. Вот простой тест:

#!/bin/bash 

V1="File Placeholder" 
#echo $V1 
V2="May contain some text" 
#echo $V2 

V3="Some command output" 
#echo $V3 
V4="Command output contains this text" 
#echo $V4 

if [[ "$V1" ]] && [[ "$V2" == *"contain some"* ]] || [[ "$V3" ]] && [[ "$V4" == *"output contains"* ]] 
then 
echo "Hello $V1" 
echo "World full of: $V2" 
fi 

Значение, я хотел бы сделать что-нибудь, если:

$V1 истинно (файл существует) И $V2 истинно (некоторая строка найдена)

ИЛИ

$V3 истинно (то есть, не нулевой) И $V4 верно (ком Выход MAND содержит текст)

Это, кажется, работает немного, но я понимаю, что это не работает должным образом: он не возвращает TRUE, если оба вторых && условия FALSE, а именно: || [[ "$V6" ]] && [[ "$V4" == *"output contains"* ]] (почему я думаю, что может быть с видом на некотором логика, возможно, может быть отменена каким-то образом?).

Почему это не работает, поскольку я предполагаю, что это будет if a AND b are TRUE ... OR ... if x AND z are TRUE?

+1

Возможно, это помогает http://stackoverflow.com/a/14965071/2442831 – Lino

+1

Спасибо! Третий пример «порядок оценки» выглядит так, как будто это может быть то, что мне нужно. Я отдам его и отчитаю. – TryTryAgain

+3

Операторы * shell * && и '||' имеют одинаковый приоритет, в отличие от обычных булевых операторов на большинстве языков. То есть 'a || b && c' совпадает с '(a || b) && c', а не' a || (b && c) '. – chepner

ответ

0

я в конце концов решил использовать «порядок оценки» подход, во-первых Ответил @Lino ссылки на третий пример в этом ответе groups of compound conditions in Bash test

if [[ "$V6" && "$V2" == *"contain some"* || ("$V3" && "$V4" == *"output contains"*) ]] 
then 
echo "Hello $V1" 
echo "World full of: $V2" 
fi 

Если это плохой подход по какой-то причине, Буду признателен за любые отзывы.

Мне нравится, как все это содержится в одной скобке [[ ]] и остается читаемой.

Все ответы и комментарии были очень полезными и просветительскими!@DKing's answer, предлагая использовать subshells, @anubhava's answer, чисто сочетая утверждения и все комментарии @ chepner!

1

Булевы условия прекращают обработку, как только у них будет достаточно информации, чтобы удовлетворить испытание. Итак, если у вас есть что-то вроде true && false && true, последнее истинное никогда не будет достигнуто. Одного ложного достаточно, чтобы знать, что весь тест будет ложным, так как вы должны иметь все истины.

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

if ([[ "$V1" ]] && [[ "$V2" == *"contain some"* ]]) || ([[ "$V3" ]] && [[ "$V4" == *"output contains"* ]]) 
then 
    echo "Hello $V1" 
    echo "World full of: $V2" 
fi 

Важно помнить, чтобы сохранить ваши условия отдельно.

+2

Лучше использовать '{...}' вместо '(...)', чтобы избежать наложения ненужной подоболочки. – chepner

+0

Это тоже работает, и хорошо знать о создании подобных подоболочек. Кроме того, спасибо @chepner за добавление ввода, это также ценная информация! – TryTryAgain

1

Вы должны использовать этот фрагмент для группировки && условий вместе в одном [[ ... ]].

if [[ -n $V1 && $V2 == *"contain some"* ]] || [[ -n $V3 && $V4 == *"output contains"* ]] 
then 
    echo "Hello $V1" 
    echo "World full of: $V2" 
fi 
+1

Мне нравится это решение много, очень аккуратный и чистый трюк, объединяющий два утверждения И! – TryTryAgain

 Смежные вопросы

  • Нет связанных вопросов^_^