Создание действий сценария оболочки

Вы можете действия по созданию для действия Automator, основывающиеся на языках сценариев с родословной UNIX, включая сценарии оболочки, Perl и Python. Эта статья объясняет, как создать такие действия.

Действие сценария оболочки выполнения

Можно включить сценарий оболочки в поток операций Automator даже, не имея необходимость создавать пакет действия. Действие Сценария оболочки Выполнения, как с Выполнением действие AppleScript, является действием, позволяющим Вам ввести и выполнить сценарий; в этом случае, однако, это - сценарий оболочки или сценарий Perl или Python. Действие Сценария оболочки Выполнения в потоке операций показывает действие в потоке операций, ищущем рекурсивно в папке Fonts для шрифтов с определенным расширением.

Рисунок 1  действие Сценария оболочки Выполнения в потоке операций
The Run Shell Script action in a workflow

Действие Сценария оболочки Выполнения в этом простом примере работает find команда в bash оболочка. Во всплывающем меню Shell можно выбрать другие оболочки (такой как csh или zsh) или Python или Perl как Ваша среда сценариев. “Ввод передачи” всплывающее меню позволяет Вам выбрать ввод в форме стандартного ввода (stdin) или как параметры оболочки.

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

Для создания основанных на сценарии оболочки действий, для которых пользователи потока операций могут выбрать опции необходимо создать пользовательское действие сценария оболочки.

Пользовательские действия сценария оболочки

Действия сценария оболочки концептуально отличаются от AppleScript и действий Objective C важными способами. Главная разница касается способа, которым ввод и пользовательский выбор передаются действию.

Вместо входного параметра, ввод передается по каналу в действие через стандартный ввод (или передается как параметры командной строки), и передал по каналу из него через стандартный вывод. Кроме того, ввод и вывод действия, вместо того, чтобы быть списком или объектом массива, является единственной строкой; отдельные элементы в строке (такие как пути) разделяются друг от друга символами новой строки. (Символ новой строки является значением по умолчанию; можно изменить отделяющийся символ программно.) Идентификатор типа для действия сценария оболочки AMAccepts и AMProvides свойства всегда com.apple.cocoa.string.

Поскольку действия сценария оболочки ограничиваются единственным типом данных, они, могло бы казаться, не работали бы хорошо с другими действиями, принимающими и обеспечивающими несовместимые типы данных. Например, как действие сценария оболочки может обработать ввод от действия, торгующего записями Адресной книги? Это - то, где действия преобразования играют важную роль. Действия преобразования преобразовывают между одним типом данных и другим. Automator невидимо вставляет надлежащее действие преобразования между действиями с несходными типами в потоке операций — но только если действие преобразования доступно. Apple обеспечивает много действий преобразования в /System/Library/Automator (действия с расширением caction), но они не могли бы подойти для Вашего действия сценария оболочки. Вы многие хотят рассмотреть создание Ваших собственных действий преобразования; посмотрите Создание Действия Преобразования для процедуры.

Пользователи выбора делают в пользовательском интерфейсе действия сценария оболочки, передаются сценарию как переменные окружения. Эти переменные соответствуют ключам, указанным для объектного экземпляра контроллера Параметров в файле пера. При создании пользовательского интерфейса Вы используете эти ключи для установления привязки между средствами управления в пользовательском интерфейсе и свойстве параметров действия.

Сценарий оболочки в действии не может непосредственно вывести на экран локализованные строки в, например, сообщения об ошибках. Однако действие сценария оболочки, которое является загружаемым пакетом, может содержать локализованные файлы пера и может локализовать его видимые свойства, такие как имя действия, приложение и описание. Посмотрите Интернационализацию Действия для подробных данных.

Действия сценария оболочки не имеют никакого прямого доступа к методам платформы Automator или, в этом отношении, любой другой платформы. Нет никакого пути в сценарии для ручной синхронизации пользовательского интерфейса и свойства параметров (updateParameters и parametersUpdated методы). И при этом Вы не можете реализовать opened и activated методы (или соответствующие подпрограммы AppleScript) для выполнения инициализации и задач синхронизации. Однако Ваш проект действия сценария оболочки может включать класс помощника Objective C или сценарий утилиты AppleScript, реализующий эти методы или подпрограммы. Сценарии оболочки могут также работать osascript инструмент для выполнения отдельных сценариев AppleScript.

Создание проекта действия сценария оболочки

Для создания проекта XCode для действия сценария оболочки запустите путем выбора New Project из меню File. В Новом Помощнике проектного менеджера выберите Shell Script Automator Action, как показано на рисунке 2, и нажмите Далее.

Рисунок 2  , Выбирающий шаблон Shell Script Automator Action
Selecting the Shell Script Automator Action template

В следующем окне помощника введите название проекта и расположение и нажмите Finish. Для удобства сделайте имя проекта то же имя, которое Вы хотите, чтобы действие имело; по умолчанию название проекта присваивается имени действия и идентификатору пакета.

Окно проекта действия сценария оболочки выводит на экран большинство элементов, появляющихся в окнах проекта других типов действия (см. рисунок 3). Эти элементы включают требуемые платформы, main.nib, Info.plist, и InfoPlist.strings. Единственное различие от других проектов main.command файл, содержащий сценарий (оболочка, Perl или Python), что Вы запишете.

Рисунок 3  окно проекта действия сценария оболочки
The project window of a shell script actionThe project window of a shell script action

main.command файл в шаблоне инициализируется с простым cat команда для передачи по каналу ввода от stdin к stdout.

Прежде чем Вы начнете работать над действием сценария оболочки, познакомитесь с инструкциями для действий, документирующихся в Руководство по проектированию для Действий.

Создание представления действия

Построение пользовательского интерфейса действия сценария оболочки является процедурой, совпадающей с для других видов действий. Считайте Построение Пользовательского интерфейса для приобретения знаний о процедуре.

Помните, что ключи, которые Вы предоставляете для привязки в области Attributes инспектора NSObjectController (экземпляр Параметров в Интерфейсном Разработчике) становятся переменными окружения, к которым Вы обращаетесь в сценарии (рисунок 4). Посредством привязки настройки различных полей, кнопок и всплывающих меню преобразовываются в значения этих переменных окружения.

Рисунок 4  параметр вводит инспектора NSObjectController
The parameter keys in the NSObjectController inspector

Если Вы собираетесь сделать действие доступным в многократных локализациях, необходимо интернационализировать и локализовать файл пера; посмотрите Интернационализацию Действия.

Свойства Automator для действий сценария оболочки

Свойства действий сценария оболочки (в Info.plist файл), мало отличаются, чем свойства действий Objective C и AppleScript. Различиями является следующее:

Вы устанавливаете весь другой Automator и регулярные свойства пакета то же как в других видах действий. Посмотрите Указание Свойств Действия для получения дополнительной информации.

Запись сценария

Когда Вы пишете сценарий оболочки или Perl или сценарий Python для действия, Вы не делаете ничего различного от того, что Вы обычно были бы, за исключением двух вещей:

Параметры действия являются пользователями настроек, сделали в средствах управления и текстовых полях пользовательского интерфейса действия. Действия реализованы для содержания их как значений в словаре. Вы получаете доступ к этим значениям через ключи, которые Вы указываете при установлении привязки действия. В AppleScript и действиях Objective C словарь параметров передается в действие, и код в каждом случае непосредственно получает значение установки с помощью одного из ключей привязки. Поскольку единственной вещью, переданной в действие сценария оболочки, является стандартный ввод, необходимо получить настройки в другом отношении. Когда действие сценария оболочки выполняется в потоке операций, класс AMShellScriptAction преобразовывает элементы в словаре параметров в переменные окружения; имя каждой переменной окружения является ключом привязки. Перечисление 1 показывает, как Вы получаете доступ к значениям переменной окружения в сценарии.

Перечисление 1  демонстрационный сценарий оболочки для действия

PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH
 
case "$sortDirection" in
0)  dir=        ;;
1)  dir="-r     ";;
esac
 
case "$sortStyle" in
0)  s=  ;;
1)  s="-n       ";;
esac
 
# note when you use "-k", the first column is 1, not 0
 
sort $dir $s -k $sortColumn
 
exit 0

Этот сценарий оболочки удостоверяется PATH переменная окружения должным образом установлена. Это тогда интерпретирует две переменные окружения в случае, если операторы и устанавливают параметры sort управляйте соответственно. Это тогда выполняет команду вида, с помощью значения третьей переменной окружения как заключительный параметр командной строки.

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

while read line; do
    cp “$line” /tmp
    echo $line
done

Сценарии Perl и сценарии Python должны следовать тем же общим руководящим принципам как сценарии оболочки. Перечисление 2 показывает пример такого сценария Perl, фильтрующего текст на основе параметров, таких как диапазон строк и диапазон полей.

Перечисление 2  сценарий Perl для действия

#!/usr/bin/env perl
# Filter Text by Position
# Pick out particular lines and fields of the input text.
 
# Grab values we care about from the UI and make sure they're integers
$line1 = $ENV{'firstLine'} + 0;
$line2 = $ENV{'lastLine'} + 0;
$f1 = $ENV{'firstField'} + 0;
$f2 = $ENV{'lastField'} + 0;
$sepnum = $ENV{'fieldSeparator'} + 0;
$outputSepNum = $ENV{'outputSeparator'} + 0;
 
# Figure out the right regex for our separator.  (whitespace, blank, tab, colon, characters)
# Later we will split the input lines on this pattern.  Splitting on "" conveniently breaks
# the line apart on character positions.
 
@regexes = ( "\\s+", " ", "\t",  ":", "" );
$regex = $regexes[ $sepnum ];
 
# And what output separator to use  (blank, tab, colon, nothing)
@oseps = ( " ", "\t", ":", "" );
$osep = $oseps[ $outputSepNum ];
 
# Grab all our input
 
@lines = <>;
$linecount = $#lines + 1;
 
# Adjust line numbers. 0 = last line, -1 = 2nd last, etc.
 
if ( $line1 <= 0 ) {
    $line1 = $linecount - $line1;
}
if ( $line2 <= 0 ) {
    $line2 = $linecount - $line2;
}
 
# And get them in the right order.
if ( $line1 > $line2 ) {
    $x = $line1; $line1 = $line2; $line2 = $x;
}
 
 
 
# Output the desired lines
 
 
for ( $l = $line1 ; $l <= $line2; $l++ ) {
    # note we are counting the first line as 1
 
    $line = $lines[$l - 1];
 
    if ( $f1 == 1 && $f2 == 0 ) {
        print $line;
    } else {
        @fields = split($regex, $line);
        $fieldcount = $#fields + 1;
        # Adjust field numbers. 0  = last field, -1 = 2nd last, etc
        if ( $f1 <= 0 ) {
            $f1 = $fieldcount - $f1;
        }
        if ( $f2 <= 0 ) {
            $f2 = $fieldcount - $f2;
        }
 
        # Get fields in right order too
        if ( $f1 > $f2 ) {
            $x = $f1; $f1 = $f2; $f2  = $x;
        }
 
 
        undef @out;
        for ( $i = $f1; $i <= $f2; $i++ ) {
            push( @out, $fields[ $i - 1 ]);
        }
 
        # Output the desired fields joined by the desired output separator.
        print join($osep, @out) . "\n";
    }
 
}
exit(0);

Отладка и тестирование действий сценария оболочки

Для общих рекомендаций для отладки действий посмотрите Тестирование и Отладку Стратегий.

Вы не можете использовать gdb или любой другой отладчик для отладки действий сценария оболочки. Однако у Вас есть несколько альтернатив для рассмотрения:

Перечисление 3 показывает тот же сценарий оболочки сортировки в Перечислении 1 с добавленными отладочными операторами.

Перечисление 3  сценарий оболочки сортировки для действия, с отладочными операторами

PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH
 
# Turn on shell debugging, and arrange for our standard error stream
# to be redirected to the console device, where it will appear in Console.app's console log window
 
set -xv
exec 2>/dev/console
 
 
# We can have our own debug messages too; by adding 1>&2 we are arranging for the
# output of this command to go to standard error (the console log) rather than standard out
# (which becomes the input to the next stage.)
 
echo starting stage 1>&2
 
# Check the value of all our environment variables - which will show us all our bindings
 
printenv 1>&2
 
case "$sortDirection" in
0)    dir=        ;;
1)    dir="-r        ";;
esac
 
case "$sortStyle" in
1)    s="-n        ";;
esac
 
# Note when you use "-k", the first column is 1, not 0
# Note that these debug statements go to standard error and thus to /tmp/log
 
echo About to sort input 1>&2
echo The command is:  sort $dir $s -k $sortColumn 1>&2
 
sort $dir $s -k $sortColumn
 
echo All finished sorting 1>&2
 
exit 0

Проверьте страницу справочника или другую документацию для языка сценариев для наблюдения, какие средства отладки доступны.