Arhn - архитектура программирования

Как запретить getopts принимать пустые или нулевые или другие параметры в качестве значения параметра

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

#!/bin/bash 

function optsGet()
{
    while getopts ":c:f" opt; do
        case $opt in
            c ) [[ -z "${OPTARG}" || "${OPTARG}" == -* ]] \
                && { echo -e "ERROR: Invalid argument\n"; exit 1; }
                CNAME="${OPTARG}.tEsTsTr"
                ;;
            f ) FORCE=true
                ;;
            \?) echo -e "Invalid option: -$OPTARG\n" >&2;;
            : ) echo -e "Missing argument for -$OPTARG\n" >&2; exit 1;;
            * ) echo -e "Unimplemented option: -$OPTARG\n" >&2; exit 1;;
        esac
    done

    shift $(($OPTIND - 1))
}

optsGet "${@}"
echo -e "CNAME: ${CNAME}\n"

но он по-прежнему принимает пустой/нуль в качестве допустимого аргумента. Итак, это работает:

san@AM0150 testtools$ ./getopts.sh -c -f
ERROR: Invalid argument

Но это не:

san@AM0150 testtools$ ./getopts.sh -c " " -f
CNAME:  .tEsTsTr

san@AM0150 testtools$ ./getopts.sh -c \  -f
CNAME:  .tEsTsTr

Я скорее ожидал Missing argument for -c ошибки. Есть ли что-то, что мне здесь не хватает? Или кто-нибудь знает обходной путь? Любой вклад будет высоко оценен. Ваше здоровье!!


Обновление (в основном на основе ответа devnull):

Просто для полноты теперь у меня есть эта маленькая функция:

function ifEmpty()
{
    local VAL=$1
    local OPT=$2

    [[ -z "${VAL}" || "${VAL}" =~ ^[[:space:]]*$ || "${VAL}" == -* ]] \
    && { echo -e "\n  ERROR: Missing argument for option: -${OPT}\n" >&2; exit 1; }
}

то это можно использовать так:

c ) ifEmpty "${OPTARG}" "${opt}"
    CNAME=${OPTARG//[[:space:]]}
    ;;

для всех вариантов, которым нужен аргумент. Ваше здоровье!!

PS. по какой-то причине *[[:space:]]* не работает при использовании в функции.


  • " " не совпадает с "", т.е. не является пустой строкой (в ней есть пробел). Если вы хотите убрать начальные пробелы, вы можете сделать это 29.08.2013
  • @John Kugelman: Вы абсолютно правы, но, возможно, это не самый распространенный сценарий. Ну, в таком случае, ты просто не используешь эту штуку. Ваше здоровье!! 30.08.2013
  • Вы можете поиграть с этим сценарием: while getopts "f:c" arg; do echo "$arg: $OPTARG"; done; shift $((OPTIND-1)); printf "Arg: %s\n" "$@" с различными последовательностями параметров. Обратите внимание, что если вы наберете ./test-getopts.sh -f -- -c, -f получит двойное тире в качестве аргумента опции. Это простое правило, которое реализует getopts (и базовая функция getopt()); это не всегда то, что люди хотят. Оправдание, что -- может быть именем файла, довольно слабое; если вы хотите указать имя файла в текущем каталоге, состоящее из двух дефисов, вы можете/должны написать ./--, конечно. 30.08.2013

Ответы:


1

-z вернет true для пустой строки, а не для строки, содержащей пробелы.

Проверьте, состоит ли строка только из пробелов. Сказать:

    c ) [[ -z "${OPTARG}" || "${OPTARG}" =~ ^[[:space:]]*$ || "${OPTARG}" == -* ]] \

вместо

    c ) [[ -z "${OPTARG}" || "${OPTARG}" == -* ]] \

Это также будет обрабатывать нулевой (\) случай.

EDIT: На самом деле это можно записать и так:

    c ) [[ -z "${OPTARG}" || "${OPTARG}" == *[[:space:]]* || "${OPTARG}" == -* ]] \
29.08.2013
  • Спасибо devnull! Думаю, я пойду с ^[[:space:]]*$. Недостатком [[:space:]]* является то, что он также считает " test" недопустимым аргументом, который в некоторых случаях может быть истинным, а может и нет. Ваше здоровье!! 29.08.2013
  • Ах! в последнем опечатка. Вместо этого следует читать *[[:space:]]*. Отредактировано выше. 29.08.2013
  • Это изменение устранит проблему " test", о которой вы упомянули. 29.08.2013
  • да! это действительно так, но мне пришлось использовать =~ вместо ==. ваше здоровье!! 29.08.2013

  • 2

    Это может быть ответ без ответа, но я бы не стал пытаться его остановить. Если -c принимает имя файла в качестве аргумента, скажем, -f может быть допустимым именем файла, как и   (пробел). Как правило, я не думаю, что сценарии оболочки должны делать «полезные» вещи, такие как обрезка пробелов или выбрасывание необычных, но технически допустимых аргументов.

    30.08.2013
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..