Скрипт с более чем одним флагом

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

Первоначально сценарии относились к языкам, исходный код которых интерпретировался во время выполнения, а не компилировался (например, оболочки, такие как bash), но он стал применяться к таким языкам, как python и perl, которые (на по крайней мере, в их нынешних воплощениях) предварительно скомпилированы в байт-код , а затем выполнены. Неоднозначность здесь заключается в том, что другие языки, такие как java, работают таким же образом, но никто не называет java «языком сценариев».

Причина, по которой они были объединены с оболочкой (я полагаю, это исходный «язык сценариев»), вероятно, потому, что они были, по крайней мере, на порядок медленнее, чем чисто компилируемые языки, и поэтому до того, как у нас были компьютеры, это различие было сделано несколько несущественным в более широком диапазоне контекстов, они в основном использовались для запуска коротких «скриптов» с одним исходным файлом. То же самое можно сказать и о большинстве динамических веб-материалов до 12-15 лет назад - большинство из них просто использовали короткие сценарии CGI с небольшим количеством (часто встроенного / встроенного) javascript (дополнительная двусмысленность : java * script * обычно исключается из категории "язык сценариев", потому что он не является универсальным).

Таким образом, при обсуждении того, что сегодня в разговорной речи (или предвзято) называется основной серверной частью «языков сценариев», вероятно, имеет смысл использовать термин объектно-ориентированные языки с динамической типизацией (вы могли бы бросить в «общего назначения» или «на стороне сервера», чтобы исключить javascript, который также является объектно-ориентированным и динамически типизированным). К ним относятся:

  • Perl

  • Python

  • PHP

  • Ruby

Они отличаются от других распространенных серверных технологий, таких как Java и C #, тем, что они используют динамический вместо статическая типизация, и это, опять же, то, почему то, что обычно подразумевается под "языком сценариев" в контексте веб-технологий, на самом деле является динамически типизированным объектно-ориентированным языком (который, безусловно, включает javascript, если мы не учитываем " на стороне сервера »). Ирония здесь в том, что это исключает языки, не относящиеся к объектно-ориентированному программированию, такие как оболочка, но оболочка все равно больше не используется в веб-программировании.

1
22.03.2019, 03:29
3 ответа

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

Например:

#!/bin/bash

self=$0

show_help () {
    cat <<END_HELP
Usage: $self [-r] [-l|-u] pathname [...]

Options:

    info about options here

END_HELP
}

recurse=0    # don't recurse by default
lowercase=1  # lowercase by default

while getopts rluh opt; do
    case $opt in
        r) recurse=1   ;;
        l) lowercase=1 ;;
        u) lowercase=0 ;;
        h) show_help
           exit ;;
        *) echo 'Error in parsing options' >&2
           exit 1
    esac
done

shift "$(( OPTIND - 1 ))"

for pathname do
    if [ -d "$pathname" ] && [ "$recurse" -eq 1 ]; then
        # recurse here
    fi
    if [ "$lowercase" -eq 1 ]; then
        # turn into lowercase
    else
        # turn into uppercase
    fi
done

Обратите внимание, что код после shiftявляется просто примером кода. Я бы посоветовал вам вместо цикла использовать findдля выполнения рекурсии (, возможно, во всех случаях, даже если флаг recursionне установлен ).

Между прочим, shiftизбавляется от всех проанализированных опций из "$@", так что в списке позиционных параметров остаются только операнды пути. Это то, что цикл впоследствии повторяет.

Код, как написано выше, использует разумные значения по умолчанию (они должны быть упомянуты в тексте справки ). Это означает, что вполне нормально запускать скрипт без каких-либо опций. В качестве примечания, запуск инструмента с без аргументов, вероятно, не должен приводить к ошибке. Работы нет, поэтому не надо делать никакой работы.

2
27.01.2020, 23:18

Что-то вроде FLAGS+=rдобавит r к FLAGS. Следовательно, для modify -r -lFLAGS будет rl. Вы должны использовать одну переменную для каждой опции (FLAG_r).

Сравнение "$2" -eq 0будет работать только в том случае, если скрипт получит два имени каталога, второе из которых будет 0. Лучшее сравнение было бы "$2" = "".

0
27.01.2020, 23:18

Вы объединяете буквы флага в одну строку, поэтому с помощью myscript -l -rвы получаете FLAGS=lr, что не равно ни l, ни r.

Вы можете использовать сопоставление с образцом вместо проверки на равенство, чтобы справиться с этим:

if [[ $FLAGS = *r* ]]; then
    echo "flag -r was given"

или добавьте отдельные переменные для каждого флага:

r_flag=
l_flag=
while getopts "rluh" opt; do
    case $opt in
        r) r_flag=1;;
...
if [[ $r_flag ]]; then
    echo "flag -r was given"

В любом случае, вы, скорее всего, захотите shift $(( OPTIND - 1 ))после цикла while getopts, чтобы опции, обрабатываемые getopts, были удалены из позиционных параметров, а то, что осталось в $1, $2... аргументы скрипта, указанные после опций.

2
27.01.2020, 23:18

Теги

Похожие вопросы