Как работать с переключателем без аргумента?

echo— это непереносимая -команда, поведение которой различается в зависимости от реализации, версии, времени компиляции -и параметра времени выполнения, а также среды.

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

В частности, со встроенной реализациейzshecho\последовательности (, такие как \n, \c, \61, \\... ), расширяются (в соответствии с требованиями POSIX. +XSI, в то время как POSIX без XSI оставляет поведение неопределенным ), если опция bsdechoне включена (отключена по умолчанию в большинстве развертываний ), а для bashони расширяются только тогда, когда xpg_echoвключено (отключено по умолчанию в большинстве развертываний ).

И zsh, иbashechoподдерживают (нестандартную -опцию)-Eдля отключения расширений (, не поддерживаемых bash, если и xpg_echo, и posix] параметры включены, хотя ).

Здесь, хотя вы могли бы сделать:

echo -E '\\' > file

Что будет нормально работать в zshи в большинстве развертываний bash, было бы гораздо лучше использовать стандартную команду printf:

printf '%s\n' '\\' > file

Чье поведение в этом случае полностью определяется POSIX и работает одинаково во всех реализациях.

Обратите внимание, что утилита printfявляется изобретением POSIX. Задолго до POSIX ответом оболочки Korn на эту не -переносимую echoпутаницу -была новая printвстроенная функция с ее -rвозможностью не расширять \xпоследовательности и -для пометки конец вариантов. zshимеет встроенный Korn -, подобный print, а bash— нет.

В кш и зш тоже можно сделать:

print -r - "$var"

Для печати произвольных данных, как -.

Подробнее на:

0
03.11.2020, 22:29
1 ответ

Использование вами getopts :rt:сообщает оболочке, что вам требуется аргумент для опции "t".

На справочной странице getopts:

[...] if a character is followed by a colon, the option is expected to have an argument, which should be separated from it by white space [...] When an option requires an argument, getopts places that argument into the variable OPTARG

Если вы хотите сделать аргумент для -t необязательным, вам нужно удалить двоеточие и обработать следующий аргумент вручную:

while getopts :rt option
do
    case "${option}" in
        r)
            REST=true
            #echo "Restart"
            ;;
        t)
            TIMEOFDAY=${!OPTIND}
            TIME=true
            case "$TIMEOFDAY" in
                n | d)
                    echo "$TIMEOFDAY"
                    ;;
                "")
                    echo "-t argument requires an option."
                    exit 2
                    ;;
                *)
                    echo "Invalid argument for -t, use only 'd' or 'n'"
                    exit 0
                    ;;
            esac
            ;;
            *)
               echo "Argument -${OPTARG} not found."
               echo "Use only -r and -t."
               exit 0
               ;;
    esac
done

В вашем коде два изменения:

  1. Изменение "optstring" с :rt:на :rtсообщает getopts, что опция "t" не требует указания аргумента.
  2. Изменена строка TIMEOFDAY=${OPTARG}на TIMEOFDAY=${!OPTIND}.

Снова из справочной страницы:

Each time it is invoked, the getopts utility shall place the value of the next option in the shell variable specified by the name operand and the index of the next argument to be processed in the shell variable OPTIND.

Таким образом, при обработке опции "t" переменная OPTIND будет иметь порядковый номер следующей опции . Синтаксис ${! переменная } косвенно ссылается на значение переменной .

Я повторно -создал его в песочнице и добавил еще одну строку, повторяющую значение OPTIND, чтобы объяснить его здесь:Попробуйте онлайн!

0
18.03.2021, 22:52

Теги

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