Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Tools & Tips
Code

Написание Shell сценария с нуля

by
Difficulty:AdvancedLength:LongLanguages:

Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)

Написание сценариев оболочки может быть довольно сложной задачей, прежде всего потому, что оболочка не является самым дружественным для использования языком. Тем не менее, я надеюсь показать вам в этом уроке, что сценарий оболочки на самом деле не такой жесткий или страшный, как вы могли ожидать.

В этом уроке мы напишем скрипт, который упростит процесс использования тестовой среды Jasmine. На самом деле, я бы не использовал этот скрипт сегодня; Я бы использовал Grunt.js или что-то подобное. Тем не менее, я написал этот скрипт до того, как появился Grunt, и я обнаружил, что это оказалось отличным способом получить более удобный интерфейс с помощью сценариев оболочки, поэтому мы его используем.

Одно замечание: этот учебник немного связан с моим предстоящим курсом Tuts + Premium «Advanced Command Line Techniques». Чтобы узнать больше о чем-либо в этом уроке, следите за обновлениями этого курса. В дальнейшем в этом уроке он будет называться «курс».

Итак, наш сценарий, который я называю jazz, будет иметь четыре основные функции:

  • Он загрузит Jasmine из Интернета, распакует его и удалит код примера.
  • Он создаст файлы JavaScript и связанные с ними файлы спецификаций и предварительно заполнит их небольшим количеством кода шаблона.
  • Он откроет тесты в браузере.
  • Он отобразит текст справки, которая описана выше.

Начнем с файла сценария.


Шаг 1 - Создание файла

Написание сценария оболочки полезно, только если вы можете использовать его с терминала; Чтобы иметь возможность использовать свои собственные сценарии на терминале, вам нужно поместить их в папку, находящуюся в переменной PATH вашего терминала (вы можете увидеть свою переменную PATH, выполнив echo $ PATH). Я создал папку ~/bin (где ~ - домашний каталог) на моем компьютере, и именно там мне нравится сохранять собственные скрипты (если вы сделаете то же самое, вам придется добавить их в свой path). Итак, просто создайте файл с названием jazz, и поместите его в свою папку.

Конечно, мы также должны сделать этот файл исполняемым; В противном случае мы не сможем его запустить. Мы можем сделать это, выполнив следующую команду:

Теперь, когда мы можем фактически выполнить скрипт, добавим очень важную часть. Все сценарии оболочки должны начинаться с shebang). Как говорит Википедия, это должна быть первая строка сценария; Он указывает, какой интерпретатор или оболочка должен запускать этот сценарий. Мы просто собираемся использовать базовую стандартную оболочку:

Хорошо, теперь когда у нас все настроено, мы готовы начать писать фактический код.


Шаг 2 - Обозначение потока скрипта

Раньше я указывал, какими должны быть разные функции нашего сценария оболочки. Но как скрипт узнает, какую функцию запустить? Мы будем использовать комбинацию параметра оболочки и оператора case. При запуске скрипта из командной строки мы будем использовать подкоманду, например:

Это должно выглядеть знакомо, особенно если вы использовали Git:

Основываясь на этом первом параметре (init, create, run, help), наш оператор case решит, что нужно запускать. Однако нам нужен вариант по умолчанию: что произойдет, если первый параметр не задан, или мы получаем нераспознанный первый параметр? В этих случаях мы покажем текст справки. Итак, начнем!


Шаг 3 - Написание текста справки

Начнем с оператора if, который проверяет наш первый параметр:

Сначала вы можете быть немного смущены, потому что оператор shell if довольно отличается от инструкции if «обычного» языка программирования. Чтобы лучше понять это, просмотрите скринкаст на условных высказываниях в курсе. Этот код проверяет наличие первого параметра ($1); Если он есть, мы выполним код then; else мы покажем текст справки.

Это хорошая идея, чтобы обернуть печать текста справки в функции, потому что нам нужно называть его более одного раза. Нам нужно определить функцию до ее вызова, поэтому мы поставим ее наверху. Мне это нравится, потому что теперь, как только я открываю файл, я вижу документацию для скрипта, которая может быть полезным напоминанием при возвращении к коду, который вы не видели долгое время. Без дальнейших церемоний, вот функция help:

Теперь просто замените эту функцию # show help вызовом функции help.


Шаг 4 - Пишем case выражения

Если есть первый параметр, нам нужно выяснить, что это такое. Для этого мы используем оператор case:

Мы передаем первый параметр в оператор case; он должен соответствовать одному из четырех вариантов: «init», «create», «run» или «wildcard», default case. Обратите внимание, что у нас нет явного случая «help»: это просто наш случай по умолчанию. Это работает, потому что ничего, кроме «init», «create» и «run», не является командами, которые мы распознаем, поэтому он должен получить текст справки.

Теперь мы готовы написать функциональный код, и мы начнем с jazz init.


Шаг 5 - Подготовка Jasmine с jazz init

Весь код, который мы пишем здесь, будет идти в нашем case init) из приведенного выше примера case. Первый шаг - фактически загрузить автономную версию Jasmine, которая входит в zip-файл:

Сначала мы выводим небольшое сообщение, а затем используем curl для загрузки zip. Флаг s делает его тихим (без вывода), а флаг O сохраняет содержимое zip в файл (в противном случае он будет выводить его). Но что такое переменная $JASMINE_LINK? Ну, вы можете поместить фактическую ссылку на zip-файл там, но я предпочитаю поместить его в переменную по двум причинам: во-первых, это не позволяет нам повторять часть пути, как вы увидите через минуту. Во-вторых, с этой переменной в верхней части файла упрощается изменение версии Jasmine, которую мы используем: просто измените эту переменную. Вот это объявление переменной (я положил ее вне оператора if вверху):

Помните, что в этой строке нет пробелов вокруг знака равенства.

Теперь, когда у нас есть наш zip-файл, мы можем разархивировать его и подготовить содержимое:

В двух из этих строк мы используем basename $JASMINE_LINK; Команда basename просто уменьшает путь до базового имени: так что path/to/file.zip становится просто file.zip. Это позволяет нам использовать переменную $JASMINE_LINK для ссылки на наш локальный zip-файл.

После того, как мы распакуем, мы удалим этот zip-файл, а также все файлы JavaScript в каталогах src и spec. Это образцы файлов, с которыми работает Jasmine, и они нам не нужны.

Затем у нас есть проблема только для Mac. По умолчанию, когда вы загружаете что-то из Интернета на Mac, когда вы пытаетесь запустить его в первый раз, вас попросят подтвердить, что вы хотите его запустить. Это связано с расширенным атрибутом com.apple.quarantine, который Apple помещает в файл. Нам нужно удалить этот атрибут.

Начнем с проверки наличия команды xattr, поскольку она не существует в некоторых Unix-системах (я не уверен, но это может быть только программа Mac). Если вы наблюдали за просмотром курсора в условных выражениях, вы узнаете, что мы можем передать любую команду в if: Если она имеет статус выхода ничего, кроме 0, то значение будет false. Если which найдет команду xattr, она выйдет с 0; В противном случае выйдет с 1. В любом случае, which отобразит некоторый вывод; Мы можем не показывать его, перенаправив в /dev/null (это специальный файл, который отбрасывает все записанные на него данные).

Этот двойной амперсанд является логическим И; Он для второго условия, которое мы хотим проверить. То есть, имеет ли SpecRunner.html этот атрибут? Мы можем просто запустить команду xattr на файле и сравнить ее вывод с строкой, которую мы ожидаем. (Мы не можем просто ожидать, что файл будет иметь этот атрибут, потому что вы можете отключить эту функцию в Mac OS X, и мы получим сообщение об ошибке при попытке удалить его, если файл не имеет атрибута).

Итак, если xattr найден и файл имеет атрибут, мы удалим его с флагом d (для удаления). Довольно просто, правда?

Последний шаг - отредактировать SpecRunner.html. В настоящее время он содержит теги скриптов для файлов примеров, которые мы удалили; Мы также должны удалить те теги скриптов. Я знаю, что те теги сценария охватывают строки от 12 до 18 в файлах. Таким образом, мы можем использовать редактор потока sed для удаления этих строк:

Флаг i сообщает sed об изменении файла на месте или для сохранения вывода из команды в тот же файл, который мы проходили; Пустая строка после флага означает, что мы не хотим, чтобы sed архивировал файл для нас; Если бы вы этого хотели, вы могли бы просто поместить расширение файла в эту строку (например, .bak, чтобы получить SpecRunner.html.bak).

Наконец, мы сообщим пользователю, что Jasmine был инициализирован. И на этом наша команда jazz init готова.


Шаг 6 - Создание файлов с помощью jazz create

Затем мы позволим нашим пользователям создавать файлы JavaScript и связанные с ними файлы спецификаций. Эта часть кода войдет в раздел «create» в case, который мы писали ранее.

При использовании jazz create нам нужно включить имя файла в качестве второго параметра: jazz create View, например. Мы будем использовать его для создания src/View.js и spec/ViewSpec.js. Итак, если нет второго параметра, мы напомним пользователю добавить его.

Если есть имя файла, мы начнем с создания этих двух файлов (внутри then части):

Конечно, вы можете поместить все, что захотите, в свой файл src. Я делаю кое что основное здесь; Поэтому jazz create View создаст src/View.js с этим содержимым:

Вы можете заменить эту первую echo строку следующим:

И тогда jazz create View приведет к следующему:

Итак, ваше воображение - это предел. Конечно, вы захотите, чтобы spec-файл был стандартным кодом спецификации Jasmine, что я и выше; Но вы можете настроить это, как вам нравится.

Следующий шаг - добавить теги скриптов для этих файлов в SpecRunner.html. Сначала это может показаться сложным: как мы можем добавить строки в середину файла программно? Еще раз, это sed, который выполняет эту работу.

Мы начинаем так же, как и раньше: редактирование на месте без резервного копирования. Затем наша команда: в строке 11 мы хотим добавить две следующие строки. Важно избегать двух новых строк, чтобы они отображались в тексте. Как вы можете видеть, это просто вставляет те два скриптовых тега, именно то, что нам нужно для этого шага.

Мы можем закончить с небольшим выводом:

И это jazz create!


Шаг 7 - Выполнение спецификаций с jazz run

Последний шаг - фактически запустить тесты. Это означает открытие файла SpecRunner.html в браузере. Здесь будет небольшая оговорка. В Mac OS X мы можем использовать команду open, чтобы открыть файл в своей программе по умолчанию; Это не будет работать ни на одной другой ОС, но я так и делаю здесь. К сожалению, нет реального межплатформенного способа сделать это, о котором я знаю. Если вы используете этот скрипт под Cygwin в Windows, вы можете использовать cygstart вместо open; В противном случае попробуйте googling «[ваш ОС] shell script open browser» и посмотрите, что можно придумать. К сожалению, некоторые версии Linux (по крайней мере, Ubuntu, по моему опыту) имеют open команду для чего-то совершенно другого. 

К настоящему времени вы точно знаете, что это значит: если у нас есть команда open, то мы откроем SpecRunner.html, иначе мы просто напечатаем сообщение, в котором пользователь должен открыть файл в браузере.

Первоначально, if условие выглядело так:

Как мы это делали с xattr, оно просто проверяло наличие open; Однако, поскольку я узнал, что в Linux существует другая команда open (даже на моем сервере Ubuntu, который даже не может открыть браузер!), Я решил, что лучше сравнить путь программы open, поскольку в Linux она находится в /bin/open (опять же, по крайней мере, на сервере Ubuntu).

Вся эта лишняя словесность об open может показаться оправданием для отсутствия у меня хорошего решения, на самом деле это указывает на что-то важное в командной строке. Не путайте понимания терминалов с пониманием конфигурации компьютера. Этот учебник и связанный с ним курс научили вас немного работе в оболочке Bash (и оболочке Z), но это не значит, что каждый компьютер, который вы используете, будет настроен одинаково; Существует множество способов установки новых команд (или разных версий команд), а также удаления команд. Предостережение разработчику.

Ну, это весь скрипт! Здесь снова, все вместе:

Ну, продолжайте, попробуйте!

Кстати, если вы хотите немного поучаствовать в этом проекте, вы можете найти его на Github.


Вывод

Итак, у вас теперь есть это! Мы только что написали сценарий оболочки промежуточного уровня; Это было не так уж плохо, не так ли? Не забудьте следить за моим предстоящим курсом Tuts + Premium; Вы узнаете гораздо больше о многих методах, используемых в этой статье, а также о многих других. Получайте удовольствие от работы в терминале!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.