Как написать shell linux
Автор: iNo // k0dsweb gr0up
Статья является собственностью команды KodsWeb (www.kodsweb.ru)
-= 06.09.2006 =-
Intro.
В данной статье я вкратце опишу shell-программирование, рассмотрю простейшие примеры и прокомментирую их. Сразу оговорюсь,что эта статья не является исчерпывающим руководством по shell-программированию. Но её будет достаточно чтобы освоить его основы. Несмотря на кажущуюся простоту shell-программирования, оно является достаточно мощным инструментом администратора unix-системы.Замечу,что для полноценного администрирования unix-системы, уметь программировать на shell просто необходимо. Все примеры протестированы на системе Slackware Linux 10.2 и полностью работоспособны.
Общие положения.
Комментарии начинаются с символа #, за исключением первой строки. Первой строкой сценария является путь к интерпретатору, начинающийся с #! с помошью которого будет запущен данный скрипт. Например:
Переменные, ввод и вывод данных.
Для задания переменных используется оператор присваевания «=». Синтаксис следующий:
В данный пример также можно добавить одинарные или двойные кавычки, от этого результат работы программы не изменится. Но не стоит использовать обратные кавычки, т.к.эти символы используются для выполнения команд:
Оператор read присваевает значение переменной.Вот пример,который просит ввести переменную var,считывает её а затем выводит.
Агрументы командной строки.
Арифметические операции.
Арифметические операции производятся с использованием оператора let. Операции:
Синтаксис арифметических операций в Shell:
Оператор test или [].
Синтаксис оператора test:
Ниже приведены все опции оператора test(или []):
Сравнение целых чисел:
Условия.
Ниже описан синтаксис всех условных операторов, с примерами.
Результат работы,при переданном параметре равном 10:
Результат работы,при переданном параметре равном 10:
Результат работы,при переданном параметре равном 7:
3) if then elif else fi
Результат работы,при переданном параметре равном 10:
Результат работы,при переданном параметре равном 9:
Результат работы,при переданном параметре равном 8:
4) case in ) ;; *) ;; esac
Case-конструкция позволяет выбирать один из нескольких альтернативных вариантов.
Результат работы,при переданном параметре равном 1:
Результат работы,при переданном параметре равном 2:
Результат работы,при переданном параметре равном 10:
Циклы.
Оператор языка shell-программирования while выполняет команды, пока условие истино.
Пример:
Оператор until выполняет команды, пока условие ложно.
Пример:
Результат работы программы,с параметрами 1 2 3 4 5:
Эта конструкция отличается от обычного for тем, что параметры берутся не из командной строки, а из строки после оператора in.
Конструкция select создаёт меню на основе элементов заданного списка, а затем выполняет для него указанную команду.
Пример:
Случайная цитата
Достойный муж делает много, но не хвалится сделанным, совершает заслуги, но не признает их, потому что он не желает обнаруживать свою мудрость.
Bash-скрипты: начало
Сегодня поговорим о bash-скриптах. Это — сценарии командной строки, написанные для оболочки bash. Существуют и другие оболочки, например — zsh, tcsh, ksh, но мы сосредоточимся на bash. Этот материал предназначен для всех желающих, единственное условие — умение работать в командной строке Linux.
Сценарии командной строки — это наборы тех же самых команд, которые можно вводить с клавиатуры, собранные в файлы и объединённые некоей общей целью. При этом результаты работы команд могут представлять либо самостоятельную ценность, либо служить входными данными для других команд. Сценарии — это мощный способ автоматизации часто выполняемых действий.
Итак, если говорить о командной строке, она позволяет выполнить несколько команд за один раз, введя их через точку с запятой:
На самом деле, если вы опробовали это в своём терминале, ваш первый bash-скрипт, в котором задействованы две команды, уже написан. Работает он так. Сначала команда pwd выводит на экран сведения о текущей рабочей директории, потом команда whoami показывает данные о пользователе, под которым вы вошли в систему.
Используя подобный подход, вы можете совмещать сколько угодно команд в одной строке, ограничение — лишь в максимальном количестве аргументов, которое можно передать программе. Определить это ограничение можно с помощью такой команды:
Командная строка — отличный инструмент, но команды в неё приходится вводить каждый раз, когда в них возникает необходимость. Что если записать набор команд в файл и просто вызывать этот файл для их выполнения? Собственно говоря, тот файл, о котором мы говорим, и называется сценарием командной строки.
Как устроены bash-скрипты
Команды оболочки отделяются знаком перевода строки, комментарии выделяют знаком решётки. Вот как это выглядит:
Тут, так же, как и в командной строке, можно записывать команды в одной строке, разделяя точкой с запятой. Однако, если писать команды на разных строках, файл легче читать. В любом случае оболочка их обработает.
Установка разрешений для файла сценария
Попытка запуска файла сценария с неправильно настроенными разрешениями
Сделаем файл исполняемым:
Теперь попытаемся его выполнить:
После настройки разрешений всё работает как надо.
Успешный запуск bash-скрипта
Вывод сообщений
Вот что получится после запуска обновлённого скрипта.
Вывод сообщений из скрипта
Использование переменных
Переменные позволяют хранить в файле сценария информацию, например — результаты работы команд для использования их другими командами.
Нет ничего плохого в исполнении отдельных команд без хранения результатов их работы, но возможности такого подхода весьма ограничены.
Существуют два типа переменных, которые можно использовать в bash-скриптах:
Переменные среды
Иногда в командах оболочки нужно работать с некими системными данными. Вот, например, как вывести домашнюю директорию текущего пользователя:
Использование переменной среды в сценарии
А что если надо вывести на экран значок доллара? Попробуем так:
В подобной ситуации поможет использование управляющего символа, обратной косой черты, перед знаком доллара:
Теперь сценарий выведет именно то, что ожидается.
Использование управляющей последовательности для вывода знака доллара
Пользовательские переменные
В дополнение к переменным среды, bash-скрипты позволяют задавать и использовать в сценарии собственные переменные. Подобные переменные хранят значение до тех пор, пока не завершится выполнение сценария.
Как и в случае с системными переменными, к пользовательским переменным можно обращаться, используя знак доллара:
Вот что получится после запуска такого сценария.
Пользовательские переменные в сценарии
Подстановка команд
Одна из самых полезных возможностей bash-скриптов — это возможность извлекать информацию из вывода команд и назначать её переменным, что позволяет использовать эту информацию где угодно в файле сценария.
Сделать это можно двумя способами.
При втором подходе то же самое записывают так:
А скрипт, в итоге, может выглядеть так:
Скрипт, сохраняющий результаты работы команды в переменной
Математические операции
Математические операции в сценарии
Управляющая конструкция if-then
А вот рабочий пример:
В данном случае, если выполнение команды pwd завершится успешно, в консоль будет выведен текст «it works».
Вот что получается после запуска этого скрипта.
В этом примере, если пользователь найден, скрипт выведет соответствующее сообщение. А если найти пользователя не удалось? В данном случае скрипт просто завершит выполнение, ничего нам не сообщив. Хотелось бы, чтобы он сказал нам и об этом, поэтому усовершенствуем код.
Управляющая конструкция if-then-else
Напишем такой скрипт:
Запуск скрипта с конструкцией if-then-else
Ну что же, продолжаем двигаться дальше и зададимся вопросом о более сложных условиях. Что если надо проверить не одно условие, а несколько? Например, если нужный пользователь найден, надо вывести одно сообщение, если выполняется ещё какое-то условие — ещё одно сообщение, и так далее. В подобной ситуации нам помогут вложенные условия. Выглядит это так:
Сравнение чисел
В скриптах можно сравнивать числовые значения. Ниже приведён список соответствующих команд.
В качестве примера опробуем один из операторов сравнения. Обратите внимание на то, что выражение заключено в квадратные скобки.
Вот что выведет эта команда.
Сравнение чисел в скриптах
Значение переменной val1 больше чем 5, в итоге выполняется ветвь then оператора сравнения и в консоль выводится соответствующее сообщение.
Сравнение строк
В сценариях можно сравнивать и строковые значения. Операторы сравнения выглядят довольно просто, однако у операций сравнения строк есть определённые особенности, которых мы коснёмся ниже. Вот список операторов.
Вот пример сравнения строк в сценарии:
В результате выполнения скрипта получим следующее.
Сравнение строк в скриптах
Вот одна особенность сравнения строк, о которой стоит упомянуть. А именно, операторы «>» и « » как команду перенаправления вывода.
Вот как работа с этими операторами выглядит в коде:
Вот результаты работы скрипта.
Сравнение строк, выведенное предупреждение
Обратите внимание на то, что скрипт, хотя и выполняется, выдаёт предупреждение:
Теперь всё работает как надо.
Она отсортирует строки из файла так:
Если его запустить, окажется, что всё наоборот — строчная буква теперь больше прописной.
Команда sort и сравнение строк в файле сценария
В командах сравнения прописные буквы меньше строчных. Сравнение строк здесь выполняется путём сравнения ASCII-кодов символов, порядок сортировки, таким образом, зависит от кодов символов.
Проверки файлов
Пожалуй, нижеприведённые команды используются в bash-скриптах чаще всего. Они позволяют проверять различные условия, касающиеся файлов. Вот список этих команд.
Эти команды, как впрочем, и многие другие рассмотренные сегодня, несложно запомнить. Их имена, являясь сокращениями от различных слов, прямо указывают на выполняемые ими проверки.
Опробуем одну из команд на практике:
Этот скрипт, для существующей директории, выведет её содержимое.
Вывод содержимого директории
Полагаем, с остальными командами вы сможете поэкспериментировать самостоятельно, все они применяются по тому же принципу.
Итоги
Сегодня мы рассказали о том, как приступить к написанию bash-скриптов и рассмотрели некоторые базовые вещи. На самом деле, тема bash-программирования огромна. Эта статья является переводом первой части большой серии из 11 материалов. Если вы хотите продолжения прямо сейчас — вот список оригиналов этих материалов. Для удобства сюда включён и тот, перевод которого вы только что прочли.
Уважаемые читатели! Просим гуру bash-программирования рассказать о том, как они добрались до вершин мастерства, поделиться секретами, а от тех, кто только что написал свой первый скрипт, ждём впечатлений.
Введение в Bash Shell
Всем привет. Это перевод из книги по подготовке к экзамену RedHat RHCE. На мой взгляд очень доступно рассказывается об основах bash.
Сценарии оболочки — наука сама по себе. Не вдаваясь в подробности всего, что происходит «под капотом», вы узнаете, как применять базовые элементы для написания собственных скриптов, и анализировать, что происходит в сторонних сценариях оболочки.
Понимание основных элементов сценариев оболочки
По сути, сценарий оболочки представляет собой список команд, которые выполняются последовательно, а также некоторую логику, позволяющую выполнять код только при определённых условиях.
Чтобы понять сложные сценарии оболочки, рекомендуется начать с базовых сценариев.
Ниже показан очень простой скрипт:
Здесь содержатся несколько элементов, которые должны использоваться во всех скриптах. Для начала, есть shebang — это строка #!/bin/bash. Когда скрипт запускается из родительской оболочки, он открывает подоболочку, в которой и выполняются команды, указанные в скрипте.
Эти команды могут быть интерпретированы различными способами. Для того, чтобы понять, как именно они должны интерпретироваться, используется shebang. В примере выше shebang ясно даёт понять, что скрипт должен выполняться оболочкой bash.
Также могут быть указаны другие оболочки. Например, если ваш скрипт содержит код на языке Perl, shebang должен быть #!/usr/bin/perl. Начинать сценарий с shebang является хорошей практикой; если он опущен, код сценария будет выполняться такой же оболочкой, которая используется для запуска скрипта.
Сразу после shebang расположена часть, объясняющая, о чем сценарий. Несколько строк комментариев в начале каждого сценария — хорошая идея. В коротком скрипте часто очевидно, что он делает, но когда сценарий становится длиннее, и по мере того, как всё больше людей вовлекаются в его написание и поддержку, становится менее понятно, что авторы намереваются сделать.
Чтобы избежать такой ситуации, убедитесь, что вы добавили строки комментариев, начиная каждую символом #. Комментарии могут быть не только в первых строках, но и в начале каждого подраздела сценария. Это наверняка поможет, если вы прочитаете свой скрипт через несколько месяцев!
Вы также можете комментировать не только подразделы, но и отдельные строки.
Независимо от того, в какой позиции он используется, всё от символа # и до конца строки является комментарием.
После блока комментариев расположено тело сценария. В вышеуказанном примере это несколько команд, выполняющихся последовательно. Тело сценария оболочки может увеличиваться по мере его развития.
В конце скрипта я включил инструкцию exit 0. Оператор выхода сообщает родительской оболочке, был ли сценарий успешным. Состояние выхода последней команды в сценарии является состоянием выхода самого сценария, если только команда exit 0 не используется в конце сценария.
Полезно знать, что вы можете работать с exit, чтобы сообщить родительской оболочке, как все прошло.
Также вы можете разместить сценарий в каталоге /bin, после чего в любом месте файловой системы просто ввести имя файла, и сценарий выполнится.
Командой vi /bin/datetime создадим в каталоге /bin файл с именем datetime. В созданный файл вставим это содержимое:
Сохранив файл, введите chmod +x /bin/datetime, чтобы дать файлу права на выполнение. Перейдите, к примеру, в домашний каталог с помощью команды cd
и просто введите datetime.
Перейдите, к примеру, в домашний каталог cd
и просто введите datetime.
Использование переменных и входных данных
bash-скрипты — это гораздо больше, чем просто список команд, которые выполняются последовательно. Одна из приятных сторон скриптов заключается в том, что они могут работать с переменными и входными данными, чтобы сделать скрипт гибким. В этом разделе вы узнаете, как с ними работать.
Использование позиционных параметров
При запуске скрипта можно использовать аргументы. Аргумент — это всё, что вы помещаете за командой сценария. Аргументы могут быть использованы для того, чтобы сделать скрипт более гибким. Возьмём команду useradd lisa. В этом примере команда — это useradd, а её аргумент — lisa — указывает, что нужно сделать.
В результате выполнения такой команды должен быть создан пользователь с именем lisa.
В тексте сценария первый аргумент обозначается $1, второй аргумент — $2 и т. д. Листинг 1 показывает, как можно использовать аргументы. Попробуйте запустить этот код, указав в качестве параметров любые имена пользователей.
Под параметрами подразумевается ввод данных перед запуском скрипта. В данном случае в качестве параметров после имени скрипта argument я указал lisa, lori и bob:
В Листинге 2 представлены два новых элемента, которые относятся к аргументам:
Итак, пока есть аргументы, тело сценария выполняется.
Тело цикла for всегда начинается с do и закрывается done, а между этими двумя ключевыми словами перечисляются команды, которые необходимо выполнить. Таким образом, пример сценария будет использовать echo для отображения значения каждого аргумента и останавливаться, когда больше нет доступных аргументов.
Давайте попробуем воспользоваться скриптом из листинга 2 в этом примере:
Переменные
Переменная — это метка, которая используется для обозначения определённого места в памяти, которое содержит определённое значение. Переменные могут быть определены статически с помощью NAME=value или динамическим способом. Существует два решения для динамического определения переменной:
Листинг 3. Пример скрипта, использующего команду read
* — на самом деле тремя источник (прим. переводчика)
Обратите внимание, что при написании команды test с квадратными скобками важно использовать пробелы после открывающей скобки и перед закрывающей скобкой, без пробелов команда не будет работать.
Обратите внимание, что оператор then следует сразу за test. Это возможно, потому что используется точка с запятой (;). Точка с запятой является разделителем команд и может заменить новую строку в скрипте.
В операторе then выполняются две команды: команда echo, которая отображает сообщение на экране, и команда read.
Команда read останавливает сценарий, чтобы пользовательский ввод мог быть обработан и сохранен в переменной TEXT. Поэтому read TEXT помещает все введённые пользователем данные в переменную TEXT, которая будет использоваться позже в скрипте.
Следующая часть представлена оператором else. Команды после оператора else выполняются во всех других случаях, что в данном случае означает «иначе, если аргумент был предоставлен». Если это так, то определяется переменная TEXT и ей присваивается текущее значение $1.
Вы можете попрактиковаться на этом примере при работе с вводом.
Использование условий и циклов
Как вы уже видели, в скрипте могут использоваться условные операторы. Эти условные операторы выполняются только в том случае, если определённое условие выполняется.
В bash есть несколько условных операторов и циклов, которые часто используются.
if then else
Подробнее о test можно узнать в справочнике командой man test.
Основная конструкция if есть if… then… fi.
Она сравнивает одно условие, как показано в следующем примере:
В листинге 3 вы увидели, как можно оценить два условия, включая else в выражении. В листинге 4 показано, как можно оценить несколько условий от if до else. Это полезно, если нужно проверить много разных значений.
Обратите внимание, что в этом примере также используются несколько команд test.
Листинг 4. Пример с if then else
Вместо написания полных операторов if… then вы можете использовать логические операторы || а также &&. || является логическим «ИЛИ» и выполнит вторую часть оператора, только если первая часть не верна; && является логическим «И» и выполнит вторую часть оператора только в том случае, если первая часть верна.
Рассмотрим эти две строки:
В первом примере выполняется проверка, чтобы увидеть, пуст ли $1. Если эта проверка верна (что, в основном, означает, что команда завершается с кодом выхода 0), выполняется вторая команда.
Во втором примере команда ping используется для проверки доступности хоста.
В этом примере используется логическое «ИЛИ» для вывода текста «node is not available» в случае неудачной команды ping.
Вы обнаружите, что часто вместо условного оператора if будут использоваться && и ||. В упражнении ниже вы можете попрактиковаться в использовании условных операторов, используя либо if… then… else, либо && и ||.
Упражнение. Использование if… then… else
В этом упражнении вы поработаете над сценарием, который проверяет что является файлом, а что каталогом.
Цикл for
Цикл for представляет собой отличное решение для обработки диапазонов данных. В листинге 5 вы можете увидеть первый пример с for, где диапазон определяется и обрабатывается, пока в этом диапазоне есть необработанные значения.
Цикл for всегда начинается с ключевого слова for, за которым следует условие, которое необходимо проверить. Затем следует ключевое слово do, за которым следуют команды, которые должны быть выполнены, если условие истинно, завершается цикл с помощью ключевого слова done.
В примере, приведённом в листинге 5, вы можете увидеть, что условие представляет собой диапазон чисел в круглых скобках, назначенных переменной COUNTER.
Внутри ((… )) вычисляются арифметические выражения и возвращается их результат. Например, в простейшем случае, конструкция a=$(( 5 + 3 )) присвоит переменной «a» значение выражения «5 + 3», или 8. Кроме того, двойные круглые скобки позволяют работать с переменными в стиле языка C.
В листинге 6 вы можете увидеть один из моих любимых однострочников с for. Диапазон определяется на этот раз как последовательность чисел, начиная со 100 и доходя до 104.
Обратите внимание, как определяется диапазон: сначала вы указываете первое число, затем две точки и указываете последнее число в диапазоне. При этом с for i in для каждого из этих номеров присваивается переменная i. Каждое из этих чисел присваивается переменной i и затем выполняется команда ping, где опция -c 1 гарантирует, что отправляется только один запрос.
Результат выполнения команды ping не учитывается, поэтому её вывод перенаправляется в /dev/null. На основании состояния выхода команды ping выполняется часть выражения за &&. Таким образом, если хост доступен, отображается строка, указывающая, что он работает.
Понимание while и until
Примечание. Так и не понял, что делает этот скрипт. В моём случае используется CentOS 7 и по умолчанию там нет monitor, хотя в скрипте явно написано: Где-то пол часа гуглил для CetOS программу monitor, но так и не нашёл. И вообще не понятно каким тут боком monitor если используется ps aux. В любом случае так и не понял, что делает этот срипт. Большая просьба помочь решить этот вопрос, чтобы откорректировать текст и/или скрипт.
Сценарий в листинге 7 состоит из двух частей. Во-первых, есть цикл while. Во-вторых, есть всё, что нужно выполнить, когда цикл while больше не оценивается как true.
Ядром цикла while является команда ps, которая имеет значение $1.
Вывод команды ps aux перенаправляются в /dev/tty11. Это позволяет позже прочитать результаты из tty11, если это необходимо, но они не отображаются по умолчанию.
После операторов while следуют команды, которые необходимо выполнить, если проверяемое условие истинно. В данном случае это команда sleep 5, которая приостанавливает выполнение скрипта на 5 секунд.
Пока условие оператора while истинно, цикл продолжает выполняться. Если же условие ложно (что в данном случае означает, что процесс больше не доступен), то цикл останавливается и могут выполняться команды, следующие за ним.