Условная конструкция if в Linux
if/then
Операторы проверки условий if/then могут быть вложенными друг в друга. Конечный результат может быть таким же, как если бы результаты проверки условий будут объеденены с помощью оператора &&
[ ( левая скобка ) явлется синонимом команды test
[[...]] - расширенный вариант команды test
Конструкция if test condition-true является точным эквивалентом конструкции if [ condition-true ]
Конструкция [[ ]] более универсальна, по сравнению с [ ], внутри этой конструкции допускается подстановка параметров и команд
Конструкция [[ ... ]] более предпочтительна, нежели [ ... ], поскольку поможет избежать некоторых логических ошибок. Например, операторы &&, ||, < и > внутри [[ ]] вполне допустимы, в то время как внутри [ ] порождают сообщения об ошибках
Оператор if проверяет код завершения любой команды, не только выражения заключенное в квадратный скобки
if cmp progit.pdf metadata.xml.gz &> /dev/null; then echo "Файлы идентичны"; else "Файлы различаются"; fi
Проверка перехода в каталог
После оператора if, ни команда test, ни квадратные скобки ( [ ] или [[]] ) не являются обязательными
~$ dir="/home/chich/testing/"
~$ if cd "$dir" 2> /dev/null; then echo "выполнен переход в каталог"; else echo "Невозможно перейти в каталог"; fi
выполнен переход в каталог
#условие, находящееся внутри квадратных скобок может быть проверено без использования оператора if
var1=20
var2=22
[[ "$var1" -ne "$var2" ]] && echo "var1 не равно var2"
Операции проверки файла
#Проверка что файл существует
[[ -e "/home/chich/test" ]] && echo "файл существует"
#Обычный файл
[[ -f "/home/chich/test" ]] && echo "обычный файл"
#Ненулевой размер файла
[[ -s "/home/chich/test" ]] && echo "Файл не пустой"
#Файл является каталогом
[[ -d "/home/chich" ]] && echo "Файл является каталогом"
#Файл является блочным устройством
[[ -b "/dev/sda3" ]] && echo "Файл является блочным устройством"
#Файл является символической ссылкой
[[ -L "/dev/core" ]] && echo "Файл является символической ссылкой"
#Файл является каналом
# -p
#Файл является символьным устройством
# -c
#Файл является сокетом
[[ -S "/run/libvirt/libvirt-admin-sock" ]] && echo "Файл является сокетом"
#Файл связан с терминальным устройством
-t
#Файл доступен для чтения пользователю запустившему сценарий
-r
#Файл доступен для записи
[[ -w "/home/chich/file1.txt" ]] && echo "Файл доступен для записи"
#Файл доступен для исполнения
-x
#Флаг suid для файлов установлен
#-u
[[ -u "/usr/bin/test.sh" ]] && echo "Флаг suid установлен"
Установленный флаг suid приводит к изменению привилегий запущенного процесса на привилегии владельца исполняемого файла
Исполняемые файлы вледельцем которых является root, с установленным флагом suid, запускаются с привилегиями root, даже если их запускает обычный пользователь
В случае отсутствия флага, программы не смогут быть запущены пользователями не обладающими привилегиями root
Файл с установленным флагом suid отображается с включенным флагом s в поле прав доступа
Это может оказаться полезным для некоторых программ (таких как pppd и cdrecord), которые осуществляют доступ к аппаратной части компьютера
chmod g+s folder
#Для файла установлен флаг sgid
[[ -g "/home/chich/folder" ]] && echo "Флаг suid установлен"
sgid - Установка ID группы во время выполнения, разрешают пользователям запускать исполняемые файлы с правами группы исполняемого файла
Если для каталога установлен флаг sgid, то файлы, создаваемые в таком каталоге, наследуют идентификатор группы каталога, получат те же разрешения
#Флаг sticky bit установлен
#-k
[[ -k "/tmp/.Test-unix" ]] && echo "Установлен флаг sticky bit"
Программы с установленным флагом "sticky bit" остаются в системном кэше после своего завершения, обеспечивая тем самым более быстрый запуск программы
Если флаг установлен для каталога, то это приводит к ограничению прав на запись
Установленный флаг "sticky bit" отображается в виде символа t в поле прав доступа
Если пользователь является владельцем каталога, с установленным флагом -t, но имеет право на запись вкаталог, тогда он может удалять только те файлы в каталоге, владельцем которых он является
Это разрешение полезно для защиты файлов от случайного удаления в среде, где несколько пользователей имеют права на запись в один и тот же каталог
sticky bit используется в основном для каталогов, чтобы защитить в них файлы. Из такого каталога пользователь может удалить только те файлы, владельцем которых он является.
Например есть пользователи user1 и user2 и оба имеют права на запись в каталог /data/work/, благодаря участию в группе work. Поэтому user1 может удалять файлы, созданные user2, и наоборот. Однако если добавить файлу флаг sticky bit, пользователь может удалять только те файлы, владельцем которых он является
Для sticky bit используйте chmod +t
#Текущий пользователь является вледельцем файла
[[ -O "file" ]] && echo "вы являетесь владельцем файла"
#Текущий пользователь состоит в группе файла
[[ -G "file" ]] && echo "вы принадлежите к той же группе, что и файл"
#Файл был модифицирован с момента последнего чтения
echo "test" > file
[[ -N "file" ]] && echo "файл был модифицирован с момента последнего чтения"
#Один файл новее или старее чем другой файл
echo test > file1.txt
ls -la | grep file
-rw-rw-r-- 1 chich chich 5 июн 19 22:31 file
-rw-rw-r-- 1 chich chich 5 июн 19 22:34 file1.txt
[[ "file1.txt" -nt "file" ]] && echo "файл file более новый чем file1"
[[ "file" -ot "file1.txt" ]] && echo "файл file более старый чем file1"
#Проверить что оба файла являются жесткими ссылками на один и тот же файл
chich@X250:~$ touch file
chich@X250:~$ echo test > file
chich@X250:~$ #Создать жесткую ссылку на file
chich@X250:~$ ln file hard1
chich@X250:~$ ln file hard2
chich@X250:~$ ls -la | grep hard
cat hard1 hard2
test
test
[[ "hard1" -ef "hard2" ]] && echo "файлы являются "жесткими" ссылками на один и тот же файл"
файлы являются жесткими ссылками на один и тот же файл
chich@X250:~$ rm file
chich@X250:~$ [[ "hard1" -ef "hard2" ]] && echo "файлы являются "жесткими" ссылками на один и тот же файл"
файлы являются жесткими ссылками на один и тот же файл
Сравнение целых чисел
chich@X250:~$ a=3
chich@X250:~$ b=5
chich@X250:~$ if [ "$a" -eq "$b" ]; then echo "Число "$a" равно "$b"";fi
chich@X250:~$
chich@X250:~$ if [ "$a" -ne "$b" ]; then echo "Число "$a" не равно "$b"";fi
Число 3 не равно 5
chich@X250:~$ if [ "$a" -gt "$b" ]; then echo "Число "$a" больше "$b"";fi
chich@X250:~$ if [ "$a" -ge "$b" ]; then echo "Число "$a" больше или равно "$b"";fi
chich@X250:~$ if [ "$a" -lt "$b" ]; then echo "Число "$a" меньше "$b"";fi
Число 3 меньше 5
chich@X250:~$ if [ "$a" -le "$b" ]; then echo "Число "$a" меньше или равно "$b"";fi
Число 3 меньше или равно 5
chich@X250:~$ #Для использования привычных операторов сравнения
chich@X250:~$ #Используются круглые скобки
chich@X250:~$ if (( "$a" > "$b" )); then echo "Число "$a" больше "$b"";fi
chich@X250:~$
chich@X250:~$ if (( "$a" >= "$b" )); then echo "Число "$a" больше или равно "$b"";fi
chich@X250:~$
chich@X250:~$ if (( "$a" < "$b" )); then echo "Число "$a" меньше "$b"";fi
Число 3 меньше 5
Сравнение строк
#Строки равны
chich@X250:~$ str1="Жили были"
chich@X250:~$ str2="Жил был"
chich@X250:~$ str3="Жили были"
if [ "$str1" = "$str3" ]; then echo "Строка str1 равна str3";fi
Строка str1 равна str3
if [ "$str1" == "$str3" ]; then echo "Строка str1 равна str3";fi
Строка str1 равна str3
#Строки не равны
if [ "$str1" != "$str2" ]; then echo "Строка str1 не равна str2";fi
Строка str1 не равна str2
#Строка пустая
if [ -z "$str1" ]; then echo "Строка str1 пустая";fi
Строка str1 пустая
if [ ! -n "$str1" ]; then echo "Строка str1 не пустая";fi
Строка str1 не пустая
Важно понимать, что если не инициализированная переменная не заключена в кавычки в условии if, то проверка будет интерпретировать такое значение как null или 0.
Поэтому проверка if [ -n $string1 ] вернет значение true, то есть строка не пустая, что будет неправильно
По этой причине при проверке переменных со строковым значеним, их необходимо заключать в кавычки
Логическое И ИЛИ
Операторы -o и -a употребляются внутри одинарных квадратных скобках
if [ "$exp1" -a "$exp2" ]
a - Логическое И как и в любом ЯП возвращает true в случае если оба выражения истинны
o - Логическое ИЛИ, как и в любом ЯП возвращает true в случае если хотябы одно из выражений истинно
Операторы a и o похожи на операторы bash && и ||
[[ condition1 && condition2 ]]
Логические операции
Логическое &&
if [ condition1 ] && [ condition2 ]
Или
if [[ condition1 && condition2 ]]
Логическое ИЛИ ||
if [ condition1 ] || [ condition2 ]
Или
if [[ condition1 || condition2 ]]
#Пример1
~$ a=10
~$ b=20
~$ if [ "$a" -eq 10 ] && [ "$b" -eq 20 ]; then echo "Бинго!"; fi
Бинго!
#Пример2
~$ if [ "$a" -eq 30 ] || [ "$b" -eq 20 ]; then echo "Бинго!"; fi
Бинго!
#Опции a и o предоставляют альтернативный вариант проверки условий
~$ if [ "$a" -eq 10 -a "$b" -eq 20 ]; then echo "Бинго!"; fi
Бинго!
~$ if [ "$a" -eq 10 -o "$b" -eq 30 ]; then echo "Бинго!"; fi
Бинго!
Источники
Связанные темы
Использование команды tee в Linux
Использование wget и curl в Linux
Команда chattr и lsattr в Linux
Использование awk Linux Alpine
Использование ifconfig в Linux
Блокировка пользователя в Linux
Проверка на необходимость перезапуска после обновления пакетов
Стандартные потоки и перенаправление ввода/вывода в Linux
Архивирование и сжатие файлов в Linux
Полезные команды и скрипты Linux
Использование оператора select в языке shell
Внутренние и внешние команды linux
Использование конструкции case в Linux