- PVSM.RU - https://www.pvsm.ru -

Машины всегда будут быстрее, независимо от того насколько мы продуктивны и как быстро мы набираем команды. Суровая правда жизни. С другой стороны, если мы выполняем одно и тоже действие множество раз, то почему бы не заставить машины страдать. Написать скрипт на bash (ваш любимый язык программирования) и каждый раз вызывать этот скрипт, а не набирать монотонные команды, которые забирают так много времени, сил и энергии. А мы, пока скрипт будет выполнять свою работу, можем помечтать о том, как космические корабли бороздят просторы нашей Вселенной.
В прошлой статье [1] мы рассмотрели основы программирования на bash. Сегодня мы будем применять полученные знания на практике.
diffdiff + Jira API_dist
В этот список попали задачи, которые я выполняю ежедневно несколько раз в день, а то и в час. Вообще, автоматизация рутинных процессов — это творческий и сугубо личный процесс. Автоматизировать можно все, что вы только можете придумать. Надеюсь, что в конце статьи у вас появится свой план по автоматизации и вы заставите машины страдать. Сделайте себе чашечку ароматного кофе и усаживайтесь поудобней. Вас ждет увлекательное путешествие в мир автоматизации средствами bash.
В своей работе на проекте мы используем Git [2]. Создание diff является довольно частой задачей. Чтобы создать diff для конкретной ветки нужно выполнить следующую команду:
git diff origin/master origin/<branch-name> > "${HOME}/diff/diff-<branch-name>.diff"
<branch-name> — имя ветки для которой нужно создать diff
Эти недостатки можно с легкостью решить при помощи bash. В идеале все должно работать так:
diffgdd <branch-name>
Теперь вместо длинной строки команд, достаточно набрать на клавиатуре ./fast_diff.sh <branch-name>. Если забыли указать имя ветки, нам об этом любезно сообщит данный скрипт.
Стоп, скажете вы. А как же финальный вид команды. Ведь в текущем виде данный скрипт не очень удобен, мы привязаны к директории в которой он находится.
Рассмотрим более подробно как сделать для исполняемого файла отдельную команду, а не писать к нему каждый раз относительный/абсолютный путь.
У каждого пользователя в его домашней директории (~) располагается поддиректория bin. Если такой нет, то ее можно создать. В ней могут хранится исполняемые файлы. Удобство заключается в том, что такие файлы доступны по имени и к ним не нужно указывать относительный/абсолютный путь. В эту директорию я поместил файл gdd, который отвечает за создание diff:
#!/bin/bash
"${HOME}/htdocs/rybka/tools/fast_diff.sh" "$@"
Два важных момента:
x (chmod +x <filename>).
Для того, чтобы этот файл стал доступным, перезапустите терминал. Теперь, чтобы создать diff, достаточно выполнить следующую команду:
gdd <branch-name>
Если вы используете в своей работе менеджер задач Jira или любой другой менеджер задач, который предоставляет cURL [3].
id задачиid задачи не передано, выводим сообщение пользователюdiff и прикрепляем его к задачеgdd_jira <issue_id>
Как вы могли заметить, имя ветки не нужно указывать. Ее мы получаем при помощи нехитрых манипуляций с командами git:
branch=$(git rev-parse --abbrev-ref HEAD)
Для начала, давайте разберемся за что отвечает директория _dist. Это место, куда попадают файлы CSS, JavaScript, всевозможные шаблоны (Jade/Pug [4], Handlebars [5], др.) и прочие файлы после запуска системы сборки (Grunt [6], Gulp [7], др.). Эта директория не обязательно должна называться _dist. Возможны вариации.

Для одного из проектов мы используем Grunt. Довольно часто наша команда сталкивается с проблемой, что Grunt не всегда замечает изменения в некоторых файлах (проблема в основном, с Less [8] файлами). Чтобы исправить эту ситуацию нужно очистить директорию _dist для одной из тем или для всех тем сразу. Да, данную задачу можно решить и с помощью Grunt. Даже можно все время удалять данную директорию вручную. Но это будет не так эффективно и удобно, как в случае с bash. Количество этих директорий (_dist) не одна и не две, и даже не десять или двадцать. Их много. Основное требование к скрипту — не применять лишние обертки и/или зависимости без необходимости.
Рассмотрим вариант без применения bash. Используем всю мощь оболочки для решения этой задачи:
find <path-to-themes> -type d -name "_dist" | xargs rm -rfv
<path-to-themes> — путь к директории, где находятся все темы
Недостатки у данного подхода примерно те же, что я приводил и в случае с задачей по созданию diff. Плюс ко всему в данном случае нет возможности указывать для какой конкретно темы нужно удалить директорию _dist.
_dist во всех темах_dist в конкретной темеclean_dist [<theme_name>]

Представьте, что вы работаете с большим проектом. В этом проекте есть директория, отведенная под сторонние репозитории, которые вы не разрабатываете, но поддерживать их в актуальном состоянии обязаны. Конечно, если этих репозиториев два-три, то это не такая большая проблема. Хотя и тут я бы поспорил. А если у вас таких репозиториев 10-15, и эта цифра постоянно растет. В результате вы не успеваете за ними следить или тратите несоизмеримо много времени на поддержку. Почему бы эту задачу не автоматизировать.
mastermaster, сделать git checkoutgit pull
Важный момент. Даже, если репозиторий находится на ветке master, мы не можем быть уверены, что он в актуальном состоянии. Исходя из этого, делаем git pull в любом случае.
up_repo
Данная задача тесно связана с предыдущим пунктом автоматизации. Чтобы конечный пользователь имел возможность воспользоваться предыдущей командой на практике, необходимо предоставить набор репозиториев сторонних разработчиков, которые будут располагаться в директории bash/core/vendors, и о которых пользователю, по большому счету, не нужно ничего знать. По аналогии с npm модулями этот набор репозиториев не должен поставляться вместе с основным репозиторием. Все что нужно сделать пользователю — это выполнить команду и дождаться завершения клонирования репозиториев.
git cloneclone_repo
У меня есть несколько вопросов к читателям. Вы должны ответить честно самому себе. Как часто вы используете эту команду?
git branch
А эту команду?
git status
А вот эту команду?
git push origin <branch-name>
Как насчет этой команды?
ps aux | grep <user-name>
Все верно, этот список можно продолжать бесконечно и он у каждого свой. И тут, неожиданно, к нам приходит озарение:

Правильно. Для команд, которые вы используете часто — создавайте алиасы. Вот лишь небольшой список тех алиасов, что я использую:
У меня даже есть алиас, чтобы посмотреть какие алиасы у меня заданы (фейспалм). Вот он:
alias showaliases='cat $HOME/.bashrc | grep alias'
В большинстве случаев для таких целей используют файл .bashrc, который располагается в домашней директории пользователя. Еще есть файл под названием .gitconfig, в который можно добавлять алиасы для работы с git.
Алиасы — это мощный инструмент. Только тут как с паролями. Не стоит менять алиасы поздно ночью. В одну прекрасную ночь, я поменял один из алиасов и забыл. На следующий день я потратил полдня, разбираясь почему ничего не работает.
Как только я начал разбираться с основами программирования на bash, первая мысль, которая меня посетила: «Стоп, это же нужно больше для системных администраторов...». Но в то же время, я понимал, что мне нужны эти знания, чтобы хоть как-то избавить себя от ежедневных рутинных задач. Сейчас я могу с уверенностью сказать, что эти знания нужны не только системным администраторам. Они пригодятся всем, кто хоть как-то взаимодействует с удаленным сервером или работает на OS *nix подобных системах. Для пользователей, которые работают на Windows OS эти знания тоже пригодятся (Bash on Ubuntu on Windows [9], Windows and Ubuntu Interoperability [10]). В простейшем случае, скрипт — это ни что иное, как простой список команд системы, записанный в файл. Такой файл может облегчить вам рабочие будни и избавит от необходимости выполнять рутинные задачи вручную.
Полезные ссылки по некоторым возможностям bash, которые были использованы в примерах:
На этом все. Спасибо за внимание. Кто дочитал до конца, отдельное спасибо.
Автор: var_bin
Источник [18]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/bash/245067
Ссылки в тексте:
[1] статье: https://habrahabr.ru/post/319670/
[2] Git: https://git-scm.com/
[3] cURL: https://curl.haxx.se/
[4] Jade/Pug: https://pugjs.org/api/getting-started.html
[5] Handlebars: http://handlebarsjs.com/
[6] Grunt: http://gruntjs.com/
[7] Gulp: http://gulpjs.com/
[8] Less: http://lesscss.org/
[9] Bash on Ubuntu on Windows: https://blogs.msdn.microsoft.com/commandline/2016/04/06/bash-on-ubuntu-on-windows-download-now-3/
[10] Windows and Ubuntu Interoperability: https://blogs.msdn.microsoft.com/wsl/2016/10/19/windows-and-ubuntu-interoperability/
[11] Перенаправление ввода/вывода: http://www.opennet.ru/docs/RUS/bash_scripting_guide/c11620.html
[12] Функции: http://www.opennet.ru/docs/RUS/bash_scripting_guide/c12483.html
[13] Массивы: http://www.opennet.ru/docs/RUS/bash_scripting_guide/c12790.html
[14] Двойные круглые скобки: http://www.opennet.ru/docs/RUS/bash_scripting_guide/x4862.html
[15] Объединение команд в цепочки (конвейер): http://www.opennet.ru/docs/RUS/bash_scripting_guide/c301.html#PIPEREF
[16] Завершение и код завершения: http://www.opennet.ru/docs/RUS/bash_scripting_guide/c2105.html
[17] Псевдонимы: http://www.opennet.ru/docs/RUS/bash_scripting_guide/c12683.html
[18] Источник: https://habrahabr.ru/post/321928/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.