244

Изучаем GNU/Linux часть 28. bash скрипты #2

Продолжаем изучать GNU/Linux и готовиться к сертификации от Red Hat (RHCSA).


Для тех, кто видит мои посты впервые - я стараюсь очень лёгким языком с нуля научить вас работать с операционной системой GNU/Linux. Зачем? Потому что - Стоит ли делать курс по RHCSA?


Предыдущие темы:

Изучаем GNU/Linux часть 27. bash скрипты #1

Изучаем GNU/Linux часть 26. Программный RAID - MD

Изучаем GNU/Linux часть 25. Управление логическими томами - LVM (RHCSA)

Изучаем GNU/Linux часть 24. Работа с файловыми системами (RHCSA)

Изучаем GNU/Linux часть 23. Основы файловых систем

Изучаем GNU/Linux часть 22. Работа с дисками (RHCSA)

Изучаем GNU/Linux часть 21. Ядро Linux

Изучаем GNU/Linux часть 20. Права на файлы (RHCSA)

Изучаем GNU/Linux часть 19. Пользователи и группы (RHCSA)

Изучаем GNU/Linux часть 18. Sudo (RHCSA)

Изучаем GNU/Linux часть 17. Su и visudo (RHCSA)

Изучаем GNU/Linux часть 16. Процессы #3: Работа с процессами (RHCSA)

Изучаем GNU/Linux часть 15. Процессы #2: Информация о процессах #2 (RHCSA)

Изучаем GNU/Linux часть 14. Процессы #1: Информация о процессах

Изучаем GNU/Linux часть 13. Bash #2: переменные (RHCSA)

Изучаем GNU/Linux часть 12. Bash #1: bash-completion, alias, type

Изучаем GNU/Linux часть 11. Стандартные потоки (RHCSA)


Ссылки на темы 1 лвла - Изучаем GNU/Linux часть 10. Текстовые редакторы nano и vi (RHCSA)


Разберём условие if

P.S. Текст из видео в комментариях.


P.P.S. Мне бы пригодилась помощь в создании большого количества заданий и вопросов для обучающихся -> Задания, вопросы и ответы

GNU/Linux

1.2K поста15.6K подписчика

Правила сообщества

Все дистрибутивы хороши.

Будьте людьми.

5
Автор поста оценил этот комментарий

В прошлый раз мы остановились на том, что сделали скрипт более универсальным – вместо двух определённых пользователей мы теперь можем создавать разных пользователей, используя переменные (cat myscript). Но сделав это мы перестали соответствовать начальным требованиям. Во первых, мы говорили, что если это группа it, то её следует предварительно добавить в sudoers. Но в нашем скрипте всего одна переменная group и какое-бы значение она не получила, она всё равно добавляется в sudoers. Если я буду добавлять пользователя с группой users, то группа users тоже попадёт в sudoers. Во вторых, мы говорили, что оболочка bash только у пользователей группы it, у users должен быть nologin. Сейчас наш скрипт подходит только для пользователей группы it. Для users мы можем создать отдельный скрипт, подходящий им. Но также можем это сделать в рамках одного скрипта.


Начнём с sudoers. Сформулируем задачу – если переменная group получит значение it, то нужно добавить такую-то строчку в sudoers. Если же переменная group получит любое другое значение, ничего в sudoers добавлять не надо. И так, у нас появилось слово если – это значит, что мы имеем дело с условиями. Bash умеет работать с условиями, для этого у него есть команда if. Синтаксис команды выглядит так - if условие then команда, которую мы хотим выполнить в случае если условие выполнилось и в конце fi, чтобы показать, где у нас заканчивается команда if. Если с командой понятно, то чем же является условие? Тоже командой – cp, ls, grep и всё в таком духе, то есть просто команда. Вы спросите – if ls, где тут условие, ls просто покажет список файлов, о каком условии идёт речь? На самом деле, if интересует не сама команда, а результат её выполнения, так называемый код выхода, или статус выхода. Обычно это числа от 0 до 255.


Мы упоминали статус выхода, когда говорили про зомби процессы – дочерний процесс при завершении должен передать родительскому свой статус выхода. Зачем? Это принятый в программировании способ родительским процессам узнать, как выполнился дочерний процесс, без необходимости копаться в выводе дочернего процесса. Для процесса, который выполнился без всяких проблем, обычно статус выхода – 0. Если же что-то пошло не так, то статус выхода другой, и по нему иногда легче понять причину проблемы. В bash-е с помощью специальной переменной ($?) можно узнать статус выхода последней выполненной команды. Давайте для примера возьмём команду ls. Просто выполнив команду и посмотрев значение переменной (echo $?), мы увидим, что код выхода - 0. Теперь давайте выполним команду ls file. Команда ругается, что такого файла нет. Посмотрим статус выхода еще раз (echo $? ). Как видите, теперь он 2. Есть определенные правила, в каких случаях какие числа пишутся, но сейчас нас интересует только 0.


Если процесс завершился с кодом 0, то считается, что всё окей. Все остальные коды считаются за ошибку. Именно так думает if. Давайте напишем маленький пример (nano test, if ls then echo Success, because exit code is $? fi, cat test; ./test). Как видите, сработала команда ls, после чего команда echo. Давайте направим вывод команды ls в никуда, чтобы не было лишней информации (nano test, if ls > /dev/null; ./test). Теперь сделаем так, чтобы if получила не 0, а что-то другое. (nano test, if ls file > /dev/null; cat test; ./test). Как видите, теперь у нас условие выдаёт не 0, а значит команда после then не сработает. Можно еще if дополнить с помощью else, которая будет запускать команду, если в if условие не сработает. Выглядит это так – if условие then команда если 0 else команда если не 0 fi. Выглядит это так (nano test, if ls file then echo Success, because exit code is $? else echo Failure, because exit status is $? fi, cat test; ./test ). Как видите, сработала вторая команда.


Окей, по какому принципу работает if разобрались. Но этого недостаточно (cat myscript) – нам нужно узнать, переменная group получила в качестве значение it или что-то другое. То есть нам нужна команда, которая сравнит значение переменной с каким-то текстом. Если всё окей, у неё статус выхода будет 0 и тогда if выполнит нужную команду. Такая команда есть, и она, можно сказать, специально написана для if. Команда выглядит как открывающаяся квадратная скобка, а после выражения внутри ( [ выражение ] ) ставится закрывающаяся квадратная скобка. Причём даже есть такая программа в /usr/bin (ll /usr/bin/[), но у bash обычно есть встроенная версия этой программы (type [), а внешняя программа может понадобится для других оболочек. Есть такая же программа с названием test (type test ) и даже более продвинутая версия с двумя скобками (type [[), но она есть на bash и паре других оболочек, а не на всех. В общем, если хотим, чтобы нашими скриптами можно было пользоваться не только на bash, будем обходиться без двойных скобок.


С помощью квадратных скобок можно сравнивать много чего – строки, числа, наличие файлов, директорий, их права и многое другое. Программа сравнивает, выдаёт значение 0 или 1, а дальше if действует так, как мы обсуждали. Я приложу ссылку, где показан синтаксис для различных сравнений (https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.ht...), а пока посмотрим нашу ситуацию. Нам нужно сравнить переменную group и текст it [ $group = it ]. Для примера, дадим переменной значение users (group=users), сравним ([ $group = it ] ) и посмотрим код выхода (echo $?). Как видите = 1, то есть неправильно. Теперь дадим переменной значение it (group=it), сравним ([ $group = it ] ) и посмотрим код выхода (echo $?). 0 – значит всё правильно. Кстати, важное замечание, если в переменной есть пробелы (group=”a b c”), то сравнение работать не будет ([ $group = it ]), так как bash превратит нашу переменную в её значение – и в выражении получится много параметров, типа ( [ a b c = it ] ), это не подходит под синтаксис. Поэтому лучше переменные брать в кавычки ( [ “$group” = it ] ). Хорошо, с выражением разобрались, вернёмся к нашему скрипту и попробуем его добавить.


Вспомним наше условие - если переменная group получит значение it, то нужно добавить такую-то строчку в sudoers. Находим нашу строчку с командой echo и окружаем её условием (if [ “$group” = it ] then … ). Тут else нам не нужен, а команды после then можно чуток подвинуть направо с помощью пробелов, чтобы было проще для глаз. Теперь вспомним второе условие - оболочка bash только у пользователей группы it, у users должен быть nologin. Тоже довольно просто – наверху создаём переменную shell, чтобы легче было её поменять при надобности и даём ей значение shell=/sbin/nologin. А в if добавляем shell=/bin/bash. И не забываем в конце указать эту переменную в качестве оболочки ( -s $shell). Если у нас группа будет it, то значение переменной в if поменяется на bash, а если не it, то условие не выполнится и переменная shell останется nologin. Попробуем запустить скрипт 2 раза – один раз для пользователя с группой it, а потом для пользователя с группой users (sudo ./myscript, tail /etc/passwd). Всё сработало. Но если посмотреть sudoers (sudo tail /etc/sudoers), можно заметить, что строчка it повторяется много раз, хотя одной строчки вполне достаточно.


Давайте решим и эту проблему. Сформулируем задачу – если мы добавляем пользователя с группой it, и если в sudoers нет нужной строчки – то её нужно создать. То есть если выполнилось первое условие, нужно проверить второе условие, и если оно тоже выполнилось – то только тогда добавлять строчку. Первое условие у нас уже прописано. После его выполнения, то есть после then пишем еще один if. Теперь нужно написать условие – если такой-то строчки нет в sudoers. Поиском строчек занимается команда grep. Посмотрим, что он нам выдаёт, если мы попытаемся найти строчку. Необязательно искать всю строчку, если есть что-то про группу it, то этого достаточно ( sudo grep ‘%it’ /etc/sudoers ). И посмотрим код выхода (echo $?) - 0. Посмотрим, что будет, если он не найдёт строчку – напишем в grep какую-то несуществующую группу, чтобы он ничего не нашел ( sudo grep ‘%itаа’ /etc/sudoers ) и посмотрим еще раз (echo $?) - 1.


И так, если строчек нету, то grep выдаёт 1, если есть – 0. Мне же нужно, чтобы запись создавалась, если строчек нету, то есть grep должен выдать 1, а if должен получить 0. Чтобы вот так вот перевернуть полученное значение, нужно после if поставить восклицательный знак. Давайте проверим на том же ls, чтобы было проще. И так, если ls не выполнился, то команда после then не должна сработать (if ls file then echo File exists fi). Как видите, ls выдал ошибку и условие провалилось. Но если мы после if поставим восклицательный знак (if ! ls file then echo File exits fi ), то ls опять же не сработал, но if перевернул значение, условие выполнилось и команда сработала. Попробуем тоже самое с нашим скриптом (if ! grep “%$group” /etc/sudoers”..). И так, прочтём – если переменная group равна it запускается второе условие – если grep не нашел упоминание группы it в sudoers, то следует добавить в sudoers эту группу.


Давайте проверим. Для начала удалим все упоминания группы it в sudoers (sudo visudo). Потом запустим наш скрипт и создадим пользователя с группой it (sudo ./myscript). Теперь добавим еще одного пользователя с группой it - (sudo ./myscript). Проверяем – всё также одна строчка. Условие работает.


Мы с вами разобрали условие if, которое добавляет вашим скриптам логики, чтобы они могли проверять какие-то условия и по результатам менять какие-то переменные или выполнять дополнительные команды. Также разобрались, для чего нужны коды выхода и использовали их для команды if. Не забудем и про программу квадратных скобок, которая позволяет нам сравнивать переменные, строки, числа и проверять файлы. Мы еще разберём, как в команде if проверять другие условия с помощью elif и много чего другого. А пока расскажите в комментариях, какие еще недостатки этого скрипта вы видите и как его можно улучшить.

Автор поста оценил этот комментарий

да ладно? =)

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Ну да, если не начать интересоваться "а как тут поставить 5 разных графических окружений", то всё довольно просто. У убунту есть графическая утилита, которая помогает ставить  драйвера. Есть маркет приложений, где есть стандартный софт. Вроде стим там тоже есть, да и если нет, можно с сайта стима скачать файлик, пару раз ткнуть, и поставится.
А дальше по запросу "ютуб смотреть" и "игры играть" больше ничего не надо - кнопочки в браузере и стиме клацать и всё.

показать ответы
0
Автор поста оценил этот комментарий
Что должен знать каждый пользователь Линукс , что бы смотреть Ютуб и в игры играть ?
Друг себе хочет установить, но каждый раз пугается всей этой клинописи.
раскрыть ветку (1)
1
Автор поста оценил этот комментарий

Разве что уметь установить операционку, это довольно просто, но всё же какие-то знания для этого нужны. Дальше ставится какой-нибудь убунту, где в пару кликов можно и драйвера поставить и стим поставить, без всяких клинописей.
Очень редко может встретиться капризное железо, где, возможно, придётся из-за какого-нибудь драйвера повозиться, но это как повезёт. В остальном проблем быть не должно.

показать ответы
1
Автор поста оценил этот комментарий

чувак, тема хорошая, но есть:

https://www.opennet.ru/docs/RUS/bash_scripting_guide/

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

спасибо!