написание shell скриптов linux
Написание 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. Часть 1
Введение
break выход из цикла for, while или until
continue выполнение следующей итерации цикла for, while или until
echo вывод аргументов, разделенных пробелами, на стандартное устройство вывода
exit выход из оболочки
export отмечает аргументы как переменные для передачи в дочерние процессы в среде
hash запоминает полные имена путей команд, указанных в качестве аргументов, чтобы не искать их при следующем обращении
kill посылает сигнал завершения процессу
pwd выводит текущий рабочий каталог
read читает строку из ввода оболочки и использует ее для присвоения значений указанным переменным.\
return заставляет функцию оболочки выйти с указанным значением
shift перемещает позиционные параметры налево
test вычисляет условное выражение
times выводит имя пользователя и системное время, использованное оболочкой и ее потомками
trap указывает команды, которые должны выполняться при получении оболочкой сигнала
unset вызывает уничтожение переменных оболочки
wait ждет выхода из дочернего процесса и сообщает выходное состояние.
И конечно же кроме встроенных команд мы будем использовать целую кучу внешних, отдельных команд-программ, с которыми мы познакомимся уже в процессе
Что необходимо знать с самого начала
1. Любой bash-скрипт должен начинаться со строки:
#!/bin/bash
в этой строке после #! указывается путь к bash-интерпретатору, поэтому если он у вас установлен в другом месте(где, вы можете узнать набрав whereis bash) поменяйте её на ваш путь.
2. Коментарии начинаются с символа # (кроме первой строки).
3. В bash переменные не имеют типа(о них речь пойдет ниже)
Переменные и параметры скрипта
Приведу как пример небольшой пример, который мы разберем:
Результат выполнения скрипта:
После того как мы познакомились как использовать переменные и передавать скрипту параметры, время познакомиться с зарезервированными переменными:
Условия
Условные операторы, думаю, знакомы практически каждому, кто хоть раз пытался на чем-то писать программы. В bash условия пишутся след. образом (как обычно на примере):
#!/bin/bash
source=$1 #в переменную source засовываем первый параметр скрипта
dest=$2 #в переменную dest засовываем второй параметр скрипта
Условия. Множественный выбор
esac #окончание оператора case.
Результат работы:
ite@ite-desktop:
UPD: Исправил некоторые ошибки
UPD: Обновил часть про условия if-then-else
Самоучитель по написанию скриптов Bash для начинающих. Часть 1
Выпускаем серию статей о том, как писать скрипты Bash. Подойдет начинающим!
Что такое Bash/Shell/Scripting
Скриптинг позволяет автоматически выполнять команды, которые в противном случае выполнялись бы интерактивно одна за другой.
Основы сценариев оболочки Bash
Не отчаивайтесь, если вы не поняли ни одного из приведенных выше определений. Это совершенно нормально, ведь именно поэтому вы читаете эту статью.
Если вы не знали, Bash Scripting является обязательным навыком для любой работы в Linux системного администрирования, даже если работодатель может не требовать этого в явном виде.
Скорее всего, в данный момент вы сидите за компьютером, открыли окно терминала и задаетесь вопросом: «Что же мне делать с этой штукой?».
Так вот, в окне терминала перед вами находится shell, а shell позволяет вам с помощью команд взаимодействовать с компьютером, следовательно, получать или хранить данные, обрабатывать информацию и выполнять различные другие простые или даже очень сложные задачи.
Попробуйте это прямо сейчас! Используйте клавиатуру и введите несколько команд, таких как date, cal, pwd или ls, после чего нажмите клавишу ENTER.
Вы только что сделали то, что с помощью команд и командной оболочки взаимодействовали с компьютером, чтобы получить текущую дату и время (date), просмотреть календарь (cal), проверить расположение текущего рабочего каталога (pwd) и получить список всех файлов и каталогов, расположенных в нем (ls).
*у нас в папке пока ничего нет, поэтому команда ls не дала вывода.
Что такое скриптинг (сценарии Bash)
Как видите, с помощью сценариев можно автоматизировать любое взаимодействие с оболочкой. Более того, теперь можно автоматически выполнять наш новый сценарий task.sh ежедневно в любое заданное время с помощью планировщика заданий cron и сохранять вывод сценария в файл при каждом его выполнении. Однако это уже другая история, а пока давайте сосредоточимся на предстоящей задаче.
Что такое Bash
Существуют различные другие интерпретаторы оболочки, такие как Korn shell, C shell и другие. Поэтому хорошей практикой является явное определение интерпретатора оболочки, который будет использоваться для интерпретации содержимого скрипта.
С этого момента все наши сценарии будут включать определение интерпретатора оболочки #!/bin/bash.
Имена файлов и разрешения
Далее давайте кратко обсудим права доступа к файлам и имена файлов. Вы, наверное, уже заметили, что для выполнения сценария shell файл должен быть сделан исполняемым с помощью команды chmod +x FILENAME. По умолчанию все вновь созданные файлы не являются исполняемыми, независимо от суффикса расширения файла.
В системах GNU/Linux команда file может быть использована для определения типа файла. Как видно из приведенного ниже примера, расширение файла не имеет никакого значения, а интерпретатор оболочки, в данном случае, имеет больший вес.
Таким образом, имя shell-сценария 0_xyz вполне допустимо, но по возможности его следует избегать.
Выполнение скриптов Bash
Относительный и абсолютный путь
Наконец, прежде чем мы запрограммируем наш первый официальный сценарий оболочки bash, давайте кратко обсудим навигацию оболочки и разницу между относительным и абсолютным путем к файлу.
К счастью, в GNU/Linux есть простой инструмент компас, который поможет вам ориентироваться в файловой системе в виде команды pwd. Эта команда при выполнении всегда выводит ваше текущее местоположение. В следующем примере используются команды cd и pwd для навигации по файловой системе GNU/Linux с использованием абсолютных и относительных путей.
Быстрый совет:
19 полезных shell-скриптов на все случаи жизни
Содержание статьи
Командная строка и те невообразимые вещи, которые с ее помощью можно творить, — визитная карточка UNIX и всех ее наследников. А где есть командная строка, там есть скрипты. И сегодня. нет, мы не будем учиться писать скрипты, мы рассмотрим наиболее полезные из них, те, что ты сможешь применять ежедневно для решения самого разного круга задач, начиная от сводки погоды и веб-сервера в одну строку и заканчивая ботом для твиттера в десять строк и скриптом для автоматического запуска любого торрент-клиента.
Сразу оговорюсь, что я вовсе не приверженец шаманизма и ни в коем случае не призываю тебя сидеть в зелено-черной консоли и набирать кучу букв, чтобы выполнить действия, для которых в графическом интерфейсе достаточно навести мышку на нужный элемент. Однако я убежден, что для решения многих задач консоль и скрипты годятся гораздо лучше графического интерфейса и поэтому пренебрегать ими никак нельзя. Тем более что любая DE позволяет создать для скрипта иконку, так что для его запуска даже не надо будет открывать консоль.
Простые примеры
Итак, не разглагольствуя понапрасну, сразу перейдем к примерам:
Эта простая команда покажет тебе внешний IP — идеальный вариант, если в Сеть ты ходишь через роутер. Все, что она делает, — просто обращается к серверу ifconfig.co, который возвращает обратно IP-шник одной строкой вместо полноценной веб-страницы.
И да, это вовсе не скрипт, это просто команда, но, чтобы превратить команду в скрипт, достаточно поместить ее в текстовый файл и первой строкой добавить так называемый шебанг, то есть символы #!, за которыми следует имя командного интерпретатора:
Далее скрипт сохраняем в каталог
/bin и назначаем права на исполнение:
Теперь его можно вызывать из командной строки командой myip.sh.
Этот скрипт позволяет получить сводку погоды на четыре дня. Принцип тут такой же, как в случае с ifconfig.co.
Сводка погоды в консоли
Xakep #212. Секреты даркнета
А так можно получить краткое описание чего-либо в Википедии, причем с помощью DNS-запроса вместо обращения к веб-серверу. Кстати, веб-сервер через командную строку тоже очень легко создать:
Данный скрипт основан на утилите netcat (nc), которую называют швейцарским армейским ножом для сетевых операций. Скрипт запускает цикл, выполняющий команду nc, которая слушает 80-й порт и в ответ на запрос отдает file.html, отправляя переданный запрос в никуда (символ означает noop, то есть пустую операцию).
С помощью простых скриптов и команд можно запросто слушать интернет-радио:
Естественно, плей-лист в формате M3U необходимо заранее скачать с сайта радиостанции. Кстати, если запустить MPlayer с аргументом —input-ipc-server=/tmp/mpvsocket, им можно будет управлять, записывая команды в файл. Например, настроить громкость:
Создай два скрипта: один для запуска, другой для остановки радио (со строкой killall mpv), повесь их на рабочий стол и настрой горячие клавиши DE на управление воспроизведением. Вуаля, у тебя готов плеер для интернет-радио, запустить который можно, просто кликнув по иконке на рабочем столе. И он почти не будет расходовать память или занимать трей.
Но отвлечемся от сетевых операций и вернемся к локальным делам.
А это уже скрипт, который запускает команду в ответ на изменение файлов в каталоге. Ее можно использовать для множества разных целей, например для автоматического включения плеера при сохранении MP3-файла. Или просто выводить уведомление на десктоп, используя в качестве команды notify-send:
Десктоп
Раз уж мы заговорили о десктопе, то продолжим. Как и консоль, его тоже можно заскриптовать. Вот, например, скрипт, загружающий случайные обои, опубликованные на reddit-канале wallpaper:
Здесь все просто. С помощью wget скрипт загружает страницу www.reddit.com/r/wallpaper, передает ее grep, который ищет на ней ссылки на imgur, выбирает случайную ссылку с помощью shuf, загружает ее опять же с помощью wget и устанавливает в качестве обоев, используя команду feh (это такой миниатюрный просмотрщик изображений, его нужно предварительно установить). Скрипт можно добавить на рабочий стол, и тогда по клику у тебя будут меняться обои.
А это скрипт для включения/выключения тачпада ноутбука: включает, если отключен, и наоборот. В своей работе использует утилиту synclient, позволяющую управлять тачпадами производства Synaptics (90% тачпадов делают они). При запуске без аргументов утилита выводит различную информацию о тачпаде, в том числе строку TouchpadOff = 1, если он активирован, и TouchpadOff = 2, если отключен. Скрипт находит это значение и в зависимости от состояния тачпада включает или отключает его.
Ту же самую команду можно использовать для создания полноценной камеры слежения, которая делает снимки в моменты, когда юзер прикасается к мыши:
Для записи полноценного видео с веб-камеры можно использовать такой скрипт:
В результате ты получишь video.avi в формате MPEG4 с битрейтом 1800 и аудиодорожкой в формате MP3 с битрейтом 128.
А так ты можешь записать скринкаст. 1366×768 — разрешение рабочего стола. Просто сделать скриншот отдельного окна всегда можно с помощью команды import:
После ее запуска значок мыши изменится на «прицел», с помощью которого можно выбрать окно. Повесив эту команду на клавиатурную комбинацию, ты получишь практически идеальную систему снятия скриншотов, абсолютно не жрущую память, как это делают специализированные приложения, постоянно висящие в трее.
Подключить и настроить внешний монитор тоже можно из командной строки:
Данный скрипт предполагает, что основной монитор носит имя LVDS, а внешний — VGA-0. Это стандартная ситуация для ноутбуков; если ты не уверен, можешь проверить вывод команды xrandr: при передаче скрипту аргумента off он отключает внешний монитор, аргумент on, в свою очередь, включает его, располагая по левую сторону от основного (аргумент —left-of LVDS в первой команде). Далее скрипт добавляет новую конфигурацию для монитора с разрешением 1920 x 1080 и активирует его. В самом конце скрипт устанавливает дефолтное значение DPI — как показывает практика, при подключении монитора с другим разрешением оно часто слетает.
Он же поможет сгенерировать нестандартное разрешение, «не поддерживаемое» монитором по умолчанию.
Google, Twitter, Dropbox и торренты
Отвлечемся от десктопных дел и поговорим о сетевых сервисах. Начнем, разумеется, с Google. Вот так будет выглядеть скрипт для получения первых десяти результатов поиска:
Скрипт делает запрос к Google с помощью уже знакомого нам curl, заменяя пробелы в поисковой строке на плюсы. Далее выискивает в ответном HTML ссылки и выводит их на экран. Все просто, хоть и кажется сложным.
Ищем в Google из командной строки
Второй популярный сервис — YouTube:
Здесь все совсем просто. Скрипт всего лишь проигрывает видео с указанным в аргументе ID с помощью плеера mpv. Естественно, youtube-dl придется установить заранее.
Как насчет твиттера? Нет проблем, вот полноценный бот, который на входе принимает команду, выполняет ее с помощью командного интерпретатора и отправляет результат указанному юзеру.
Скрипт использует консольный клиент ttytter, читая в цикле последнее direct message, далее он проверяет, не была ли такая команда уже выполнена, и, если нет, выполняет ее и отправляет указанному в переменной USER пользователю, попутно обрезая до 140 символов.
Чтобы все заработало как надо, тебе придется установить ttytter, запустить его, ввести приведенную им ссылку в адресную строку браузера, скопировать показанный браузером ключ аутентификации и ввести его в ttytter. Естественно, перед тем как это сделать, следует завести для бота отдельного юзера и залогиниться под его учеткой.
Ttytter запрашивает ключ
Твиттер можно использовать не только для выполнения команд, но и для мониторинга машины. Следующий скрипт отправляет в ленту сообщение с информацией о состоянии машины (имя хоста, uptime, нагрузка, свободная память и нагрузка на CPU):
Мониторинг машины с помощью Twitter
Ну и под конец приведу скрипт, не связанный с сетевыми сервисами, но имеющий прямое отношение к сетям и к тому, зачем мы обычно их используем. Это скрипт для запуска и остановки торрент-клиента во время простоя машины:
Скрипт уходит в бесконечный цикл, каждую минуту проверяя, сколько миллисекунд прошло с момента, когда юзер что-либо делал (для этого используется команда xprintidle). Если прошло уже 600 000 мс (десять минут), скрипт выполняет команду, указанную в переменной STARTCMD. В противном случае он выполнит команду STOPCMD, но только тогда, когда до нее была выполнена команда STARTCMD. Если кратко: ничего не делаешь за компом десять минут — запускается STARTCMD, в данном случае это команда запуска всех закачек с помощью Transmission, если нет — приостановка всех закачек. Не любишь Transmission? Нет проблем, вот команды для Deluge:
Вместо выводов
Не удивлюсь, если все описанное в статье покажется тебе очередным велосипедостроением, и даже соглашусь с таким мнением. Все-таки современный Linux — это не та система для сумасшедших экспериментаторов, какой она была пятнадцать лет назад. Сегодня для каждой задачи можно найти отдельный, отлаженный и хорошо работающий инструмент, в том числе графический. Другое дело, что не совсем понятно, стоит ли захламлять систему тяжеловесными написанными на Python приложениями с кучей зависимостей, когда ту же задачу легко решить с помощью простенького скрипта.
Каким путем пойти — выбирать тебе. Встанешь ли ты на темную сторону или выберешь путь джедая?
Евгений Зобнин
Редактор рубрики X-Mobile. По совместительству сисадмин. Большой фанат Linux, Plan 9, гаджетов и древних видеоигр.
Titiaiev / bash-guide-1.md
Бесплатная книга-сайт на русском, полный гайд
Advanced Bash-Scripting Guide
BASH — Bourne-Again SHell (что может переводится как «перерожденный шел», или «Снова шел Борна(создатель sh)»), самый популярный командный интерпретатор в юниксоподобных системах, в особенности в GNU/Linux. Ниже приведу ряд встроенных команд, которые мы будем использовать для создания своих скриптов.
break выход из цикла for, while или until
continue выполнение следующей итерации цикла for, while или until
echo вывод аргументов, разделенных пробелами, на стандартное устройство вывода
exit выход из оболочки
export отмечает аргументы как переменные для передачи в дочерние процессы в среде
hash запоминает полные имена путей команд, указанных в качестве аргументов, чтобы не искать их при следующем обращении
kill посылает сигнал завершения процессу
pwd выводит текущий рабочий каталог
read читает строку из ввода оболочки и использует ее для присвоения значений указанным переменным.\
return заставляет функцию оболочки выйти с указанным значением
shift перемещает позиционные параметры налево
test вычисляет условное выражение
times выводит имя пользователя и системное время, использованное оболочкой и ее потомками
trap указывает команды, которые должны выполняться при получении оболочкой сигнала
unset вызывает уничтожение переменных оболочки
wait ждет выхода из дочернего процесса и сообщает выходное состояние.
И конечно же кроме встроенных команд мы будем использовать целую кучу внешних, отдельных команд-программ, с которыми мы познакомимся уже в процессе
Что необходимо знать с самого начала
в этой строке после #! указывается путь к bash-интерпретатору, поэтому если он у вас установлен в другом месте(где, вы можете узнать набрав whereis bash ) поменяйте её на ваш путь.
Переменные и параметры скрипта
Приведу как пример небольшой пример, который мы разберем:
Результат выполнения скрипта:
После того как мы познакомились как использовать переменные и передавать скрипту параметры, время познакомиться с зарезервированными переменными:
Условные операторы, думаю, знакомы практически каждому, кто хоть раз пытался на чем-то писать программы. В bash условия пишутся след. образом (как обычно на примере):
#!/bin/bash
#в переменную source засовываем первый параметр скрипта
source=$1
#в переменную dest засовываем второй параметр скрипта
dest=$2
Результат выполнения скрипта:
Структура if-then-else используется следующим образом:
для построения многоярусных условий вида:
для краткости и читаемости кода, можно использовать структуру:
Условия. Множественный выбор
Если необходимо сравнивать какоую-то одну переменную с большим количеством параметров, то целесообразней использовать оператор case.
esac #окончание оператора case.
После выбор цифры и нажатия Enter запуститься тот редактор, который вы выбрали(если конечно все пути указаны правильно, и у вас установлены эти редакторы 🙂 )
Прведу список логических операторв, которые используются для конструкции if-then-else-fi:
-z # строка пуста
-n # строка не пуста
=, (==) # строки равны
!= # строки неравны
-eq # равно
-ne # неравно
-lt,( # меньше
-le,( # меньше или равно
-gt,(>) #больше
-ge,(>=) #больше или равно
! #отрицание логического выражения
-a,(&&) #логическое «И»
-o,(||) # логическое «ИЛИ»
С основами языка и условиями мы разобрались, чтобы не перегружать статью, разобью её на несколько частей(допустим на 3). Во второй части разберем операторы цикла и выполнение математических операций.
Оператор for-in предназначен для поочередного обращения к значениям перечисленным в списке. Каждое значение поочередно в списке присваивается переменной.
Синтаксис следующий:
Рассмотрим небольшой пример:
Цикл while сложнее цикла for-in и используется для повторения команд, пока какое-то выражение истинно( код возврата = 0).
Синтаксис оператора следующий:
Пример работы цикла рассмотрим на следующем примере:
А теперь результат работы скрипта:
Как видим цикл выполняется до тех пор, пока мы не введем что-то отличное от «yes». Между do и done можно описывать любые структуры, операторы и т.п., все они будут выполнятся в цикле.Но следует быть осторожным с этим циклом, если вы запустите на выполнение в нём какую-либо команду, без изменения переменной выражения, вы можете попасть в бесконечный цикл.
Рассмотрим еще один пример, я взял его из книги Advanced Bash Scripting. Уж очень он мне понравился :), но я его немного упростил. В этом примере мы познакомимся с еще одним типом циклов UNTIL-DO. Эта практически полный аналог цикла WHILE-DO, только выполняется пока какое-то выражение ложно.
Вот пример:
Результат выполнения скрипта:
Ну вот, как видите ничего сложного, список математических операций стандартный:
+ — сложение
— — вычитание
* — умножение
/ — деление
** — возведение в степень
% — модуль(деление по модулю), остаток от деления
let позволяет использовать сокращения арифметических команд, тем самым сокращая кол-во используемых переменных. Например: a = a+b эквивалентно a +=b и т.д
Работа с внешними программами при написании shell-скриптов
Для начала немного полезной теории.
Если есть необходимость дописывать в файл(при использовании » > » он заменятеся), необходимо вместо » > » использовать » >> «
после просьбы sudo ввести пароль, он возьмется из файла my_password, как будто вы его ввели с клавиатуры.
Если необходимо записать в файл только ошибки, которые могли возникнуть при работе программы, то можно использовать:
символ » & » означает указатель на дескриптор 1(stdout)
(Поумолчанию stderr пишет на ту консоль, в котрой работает пользователь(вренее пишет на дисплей)).
Конвеер — очень мощный инструмент для работы с консолью Bash. Синтаксис простой:
команда1 | команда 2 — означает, что вывод команды 1 передастся на ввод команде 2
Конвееры можно группировать в цепочки и выводить с помощью перенаправления в файл, например:
Чаще всего скрипты на Bash используются в качестве автоматизации каких-то рутинных операций в консоли, отсюда иногда возникает необходимость в обработке stdout одной команды и передача на stdin другой команде, при этом результат выполнения одной команды должен быть неким образом обработан. В этом разделе я постораюсь объяснить основные принципы работы с внешними командами внутри скрипта. Думаю что примеров я привел достаточно и можно теперь писать только основные моменты.
1. Передача вывода в переменную.
Для того чтобы записать в переменную вывод какой-либо команды, достаточно заключить команду в « ковычки, например
Результат работы: qwerty
Однако если вы захотите записать в переменную список директорий, то необходимо, должным образом обработать результат для помещения данных в переменную. Рассмотрим небольшой, пример: