- sh AND and OR in one command
- Linux. Команда test
- Проверка типа файла
- Сравнение строк
- Сравнение целых чисел
- Операции AND и OR
- How to combine AND and OR condition in bash script for if condition?
- 3 Answers 3
- Проверка условий в bash
- Скобки
- Конструкции простой проверки if|then|else
- Арифметика
- Вложение нескольких проверок
sh AND and OR in one command
Trying to check for 3 conditions in one line of code, but I’m stuck. Essentially, I need to code for the following:
IF string1 is not equal to string2 AND string3 is not equal to string4 OR bool1 = true THEN display «conditions met — running code . «.
#!/bin/sh string1="a" string2="b" string3="c" string4="d" bool1=true # the easy-to-read way . if [ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] ; then echo "conditions met - running code . " fi if $bool1 ; then echo "conditions met - running code . " fi # or the shorter way . [ "$string1" != "$string2" ] && [ "$string3" != "$string4" ] && echo "conditions met - running code . " $bool1 && echo "conditions met - running code . "
The code above will potentially run twice: if the first 2 conditions are met, and then again if the 3rd condition is met. This is not what I need. The issue with this example is that it involves 2 distinct calls to ‘echo’ — (note: in the real code, it’s not an echo, but you get the idea). I’m trying to reduce the code duplication by combining the 3 condition check into a single command. I’m sure there’s a few people now shaking their heads and shouting at the screen «That’s NOT how you do it!» And there’s probably others waiting to mark this as a duplicate . well, I looked but I’m damned if I could figure out how to do this from the answers I’ve read. Can someone please enlighten me ? 🙂
Linux. Команда test
Предназначена для проверки типа файла и сравнения чисел и строк. Возвращает код возврата 0 (истина) или 1 (ложь) в зависимости от вычисления выражения. Выражения могут быть как унарными, так и бинарными.
Для сокращения кода сценария используют парный оператор [ как синоним test . Парный оператор требует пробела между скобками потому, что [ (скобка) является командой оболочки.
Проверка типа файла
- -d file — истина, если file существует и является каталогом
- -e file — истина, если file существует
- -f file — истина, если file существует и является обычным файлом
- -r file — истина, если file существует и доступен для чтения
- -s file — истина, если file существует и имеет размер больше, чем ноль
- -w file — истина, если file существует и доступен для записи
- -x file — истина, если file существует и доступен для выполнения
- -L file — истина, если file существует и является символьной ссылкой
- file1 -nt file2 — истина, если file1 новее (дата модификации), чем file2
- file1 -ot file2 — истина, если file1 старее, чем file2
#!/bin/bash if [ -f "$HOME/.bashrc" ]; then echo "Файл существует!" else echo "Файл не существует!" fi
Сравнение строк
- -z string — истина, если длина string равна нулю
- -n string — истина, если длина string не ноль
- string1 = string2 — истина, если строки равны
- string1 != string2 — истина, если строки не равны
Сравнение целых чисел
- число1 -eq число2 — истина, если число1 равно число2
- число1 -gt число2 — истина, если число1 больше число2
- число1 -ge число2 — истина, если число1 больше или равно число2
- число1 -lt число2 — истина, если число1 меньше число2
- число1 -le число2 — истина, если число1 меньше или равно число2
- число1 -ne число2 — истина, если число1 не равно число2
#!/bin/bash if [ 3 -lt 6 ]; then echo "Истина" else echo "Ложь" fi
Операции AND и OR
- expr1 -a expr2 — истина, если оба выражения expr1 и expr2 истина (операция AND)
- expr1 -o expr2 — истина, если хотя бы одно из выражений expr1 или expr2 истина (операция OR)
- ! expr — истина, если выражение expr ложно
В условном выражении команды test можно использовать круглые скобки, чтобы изменить порядок вычисления, но их нужно экранировать:
$ [ \( "$count" -ge 0 \) -a \( "$count" -lt 10 \) ]
« [[…]] » — расширенный вариант от « […] », оболочка выполняет его как один элемент с кодом возврата. Внутри « [[…]] » разрешается выполнение операторов && , || которые приводят к ошибке в обычных скобках « […] ».
#!/bin/bash if [[ -f "$HOME/.bashrc" && -f "/usr/bin/nano" ]]; then echo "Все в порядке, можно редактировать!" else echo "Ошибка!" fi
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
- 1С:Предприятие (31)
- API (29)
- Bash (43)
- CLI (99)
- CMS (139)
- CSS (50)
- Frontend (75)
- HTML (66)
- JavaScript (150)
- Laravel (72)
- Linux (146)
- MySQL (76)
- PHP (125)
- React.js (66)
- SSH (27)
- Ubuntu (68)
- Web-разработка (509)
- WordPress (73)
- Yii2 (69)
- БазаДанных (95)
- Битрикс (66)
- Блог (29)
- Верстка (43)
- ИнтернетМагаз… (84)
- КаталогТоваров (87)
- Класс (30)
- Клиент (27)
- Ключ (28)
- Команда (68)
- Компонент (60)
- Конфигурация (62)
- Корзина (32)
- ЛокальнаяСеть (28)
- Модуль (34)
- Навигация (31)
- Настройка (140)
- ПанельУправле… (29)
- Плагин (33)
- Пользователь (26)
- Практика (99)
- Сервер (74)
- Событие (27)
- Теория (105)
- Установка (66)
- Файл (47)
- Форма (58)
- Фреймворк (192)
- Функция (36)
- ШаблонСайта (68)
How to combine AND and OR condition in bash script for if condition?
I was trying to combine logical AND & OR in a bash script within if condition. Somehow I am not getting the desired output and it is hard to troubleshoot. I am trying to validate the input parameters passed to a shell script for no parameter and the first parameter passed is valid or not.
if [ "$#" -ne 1 ] && ([ "$1" == "ABC" ] || [ "$1" == "DEF" ] || [ "$1" == "GHI" ] || [ "$1" == "JKL" ]) then echo "Usage: ./myscript.sh [ABC | DEF | GHI | JKL]" exit 1 fi
3 Answers 3
The immediate problem with your statement is one of logic: you probably meant to write:
if [ "$#" -ne 1 ] || ! ([ "$1" = "ABC" ] || [ "$1" = "DEF" ] || [ "$1" = "GHI" ] || [ "$1" = "JKL" ]) then echo "Usage: ./myscript.sh [ABC | DEF | GHI | JKL]" >&2 exit 1 fi
That is: abort, if either more than 1 argument is given OR if the single argument given does NOT equal one of the acceptable values.
Note the ! to negate the expression in parentheses and the use of the POSIX-compliant form of the string equality operator, = (rather than == ).
However, given that you’re using Bash, you can make do with a single [[ . ]] conditional and Bash’s regular-expression matching operator, =~ :
if [[ $# -ne 1 || ! $1 =~ ^(ABC|DEF|GHI|JKL)$ ]] then echo "Usage: ./myscript.sh [ABC | DEF | GHI | JKL]" >&2 exit 1 fi
If POSIX compliance is not required, [[ . ]] is preferable to [ . ] for a variety of reasons. In the case at hand, $# and $1 didn’t need quoting, and || could be used inside the conditional.
Note that =~ as used above works in Bash 3.2+, whereas the implicit extglob syntax used in anubhava’s helpful answer requires Bash 4.1+;
in earlier versions you can, however, explicitly enable (and restore to its original value after) the extglob shell option: shopt -s extglob .
Проверка условий в bash
Часто при написании скриптов под bash необходимо проверять результаты выполнения тех или иных команд.
Это немного подправленная выдержка из этой статьи .
Скобки
[ — является специальной встроенной командой test воспринимающей свои аргументы как выражение сравнения или файловую проверку […..].
[[ — расширенный вариант от «[«, является зарезервированным словом, а не командой, его bash выполняет как один элемент с кодом возврата. Внутри «[[….]]» разрешается выполнение операторов &&, || которые приводят к ошибке в обычных скобках «[….]» тем самым вариант с двойной скобкой более универсален.
(( — является арифметическими выражениями, которое так же возвращают код 0. Тем самым такие выражения могут участвовать в операциях сравнения.
Приведу список логических операторов, которые используются для if|then|else:
-z – строка пуста
-n – строка не пуста
=, ( == ) – строки равны
!= – строки неравны
-ne – неравно
-gt,(>) – больше
-ge,(>=) — больше или равно
! — отрицание логического выражения
-a,(&&) – логическое «И»
-o,(||) -логическое «ИЛИ»
Конструкции простой проверки if|then
if [[ condition ]]; then commands fi
Другими словами:
если проверяемое_выражение_или_команды_верны; то выполняем команды закрываем если
#!/bin/bash if echo Тест; then echo 0 fi
Часто встречается в скриптах проверка — «существует ли файлы или каталоги» на их примере покажу работу
#!/bin/bash if [ -f $HOME/.bashrc ]; then echo "Файл существует!" fi
$HOME/.bashrc – путь до файла
echo – печатает сообщение в консоль
#!/bin/bash if [[ -f $HOME/.bashrc && -f /usr/bin/nano ]]; then echo "Все впорядке, можно редактировать!" fi
&& — логическое «и», если первый путь «истина» проверяем второй, если он тоже «истина», то выполняем команды (echo)
-f – ключ проверки на существования файла (о них чуть ниже)
Конструкции простой проверки if|then|else
if [[ condition ]]; then commands 1 else commands 2 fi
если проверяемое_выражение_или_команды_верны; то команды 1 иначе команды 2 закрываем если
Возможно не лучший пример, нас интересует именно ответ 0 или 1. В результате печатается в консоль «Тест» и «0» потому что команда «echo Тест» успешна и это «истина».
#!/bin/bash if echo Тест; then echo 0 else echo 1 fi
Намерено допустите ошибку изменив echo, в результате получите «1» и сообщение о том что «команда echo не существует» и это «ложь».
#!/bin/bash if echo Тест; then echo 0 else echo 1 fi
Примеры «существуют ли файл?»
Если файл bashrc существует, то печатает в консоль «Файл существует!», иначе печатает «Файл не существует!»
#!/bin/bash if [ -f "$HOME/.bashrc" ]; then echo "Файл существует!" else echo "Файл не существует!" fi
Поиграйте с именем проверяемого файла
#!/bin/bash if [[ -f "$HOME/.bashrc" && -f "/usr/bin/nano" ]]; then echo "Все в порядке, можно редактировать!" else echo "Ошибка!" fi
Ключи к файлам и каталогам
[ -ключ “путь” ]
[ -e “путь каталогу_или_файлу”] – существует ли файл или каталог.
[ -r “путь к файлу/каталогу”] – доступен ли файл/каталог для чтения.
[ -f “путь к файлу/каталогу”] – существует ли файл.
[ -d “путь к каталогу”] – существует ли каталог.
Полное описание возможных применений различных скобок, правильное расставление кавычек уходит далеко от темы, поэтому могу посоветовать обратится к руководству Advanced Bash Scripting
Арифметика
Если оператор > использовать внутри [[….]], он рассматривается как оператор сравнения строк, а не чисел. Поэтому операторам > и < для сравнения чисел лучше заключить в круглые скобки.
Используем круглые скобки для математического сравнение. Если «3» меньше «6» печатаем «Да».
#!/bin/bash if (( 3 6));then echo Да fi
Использование команды test, коей являются квадратные скобки. Если «3» меньше «6» печатаем «Да».
#!/bin/bash if [ 3 -lt 6 ]; then echo Да fi
Можно использовать и двойные квадратные скобки, это расширенный вариант команды test, эквивалентом которой является «[ ]». Если «3» меньше «6» печатаем «Да».
#!/bin/bash if [[ 3 -lt 6 ]]; then echo Да fi
Используем двойные квадратные скобки, потому что применяем оператор «&&». Если первое выражение 2 = 2 (истина) тогда выполняем второе, и если оно тоже 2=2 (истина), печатаем «Верно»
#!/bin/bash a="2" b="2" if [[ 2 = "$a" && 2 = "$b" ]] ; then echo Верно else echo Не верно fi
Если первое выражение 2 = 2 (истина) тогда выполняем второе, и если переменная «b» не равна двум (ложь), печатаем «Не верно»
#!/bin/bash a="2" b="3" if [[ 2 = "$a" && 2 = "$b" ]] ; then echo Верно else echo Не верно fi
Можно конечно сделать проще, нам главное понять принцип if|then и else, не стесняйтесь менять, подставляя свои значения.
Вложение нескольких проверок
Bash позволяет вкладывать в блок несколько блоков
#!/bin/bash if [[ condition 1 ]]; then if [[ condition 2 ]]; then command 1 else command 2 fi else command 3 fi
Построения многоярусных конструкций
Для построения многоярусных конструкции, когда необходимо выполнять множество проверок лучше использовать elif — это краткая форма записи конструкции else if.
if [[ condition 1 ]]; then command 1 command 2 elif [[ condition 2 ]]; then command 3 command 4 else command 5 fi