BASH getopts несколько сценариев с одинаковыми параметрами - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть серия скриптов BASH.

Я использую getopts для разбора аргументов из строки cmd (хотя открыта для альтернатив).

В этих сценариях есть ряд общих опций, называющих эти опции набором A т.е. очередь, ядро ​​и т. д.

Каждый сценарий имеет ряд дополнительных параметров, например, набор B1, B2, B3.

То, что я хочу, для сценария

"1 to be able to take options  A+B1"
"2 to be able to take options  A+B2"
"3 to be able to take options  A+B2"

Но я хочу иметь возможность хранить код для опций A в центральном месте (библиотека / функция) с необходимостью записи в каждом сценарии.

Мне нужен способ вставки общего кода в getopts. Или как вариант запустить getopts дважды.

На самом деле я сделал это, используя getopts в качестве функции, которая была получена.

Но проблема в том, что я не могу получить нераспознанную опцию для их работы. Я полагаю, что одним из способов было бы удалить аргументы из опций A из строки, прежде чем переходить к getopts для B1, B2, B3 и т. Д.?

Спасибо, Роджер

1 Ответ

0 голосов
/ 23 января 2019

Это очень хороший вопрос, для ответа на который нам нужно хорошо понять, как работает getopts.

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

#!/usr/bin/env bash
# File_1

getopts_common() {
    builtin getopts ":ab:${1}" ${2} ${@:3} || return 1
    case ${!2} in
        'a')
            echo 'a triggered'
            continue
            ;;
        'b')
            echo "b argument supplied -- ${OPTARG}"
            continue
            ;;
        ':')
            echo "MISSING ARGUMENT for option -- ${OPTARG}" >&2
            exit 1
            ;;
    esac
}

#!/usr/bin/env bash
# File_2
# source "File_1"

while getopts_common 'xy:' OPTKEY ${@}; do
    case ${OPTKEY} in
        'x')
            echo 'x triggered'
            ;;
        'y')
            echo "y argument supplied -- ${OPTARG}"
            ;;
        '?')
            echo "INVALID OPTION -- ${OPTARG}" >&2
            exit 1
            ;;
        ':')
            echo "MISSING ARGUMENT for option -- ${OPTARG}" >&2
            exit 1
            ;;
        *)
            echo "UNIMPLEMENTED OPTION -- ${OPTKEY}" >&2
            exit 1
            ;;
    esac
done

Замечания по реализации

Мы начинаем с File_2, поскольку здесь начинается выполнение скрипта:

  • Вместо прямого вызова getopts мы вызываем его через его прокси: getopts_common, который отвечает за обработку всех распространенных опций.

  • getopts_common функция вызывается с:

    1. Строка, определяющая, какие параметры ожидать и где ожидать их аргументы. Эта строка охватывает только параметры, определенные в File_2.

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

    3. Список аргументов командной строки. (Это упрощает доступ к ним изнутри getopts_common функции.)

Переходя к исходному файлу (File_1), мы должны помнить, что getopts_common функция выполняется внутри цикла while , определенного в File_2:

  • getopts возвращает false, если ничего не осталось для анализа, || return 1 бит гарантирует, что функция getopts_common делает то же самое.

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

  • Тихая отчетность об ошибках (включается, когда OPTSPEC начинается с :) позволяет нам различать INVALID OPTION и MISSING ARGUMENT. Последняя ошибка характерна для общих опций, определенных в File_1, поэтому ее необходимо перехватить там.

Для получения более подробной информации о getopts см. Bash Hackers Wiki: руководство Getopts

...