Как правильно проверить наличие символа "?" в протоколе дела

У меня ниже сценария Bash с помощью getopts, Мой код работает должным образом, т. Е. Когда указана неверная опция, переменная $myopt установлена ​​в '?' символ и инструкция case корректно обрабатывают код, соответствующий '?'.
Иначе, где я вижу похожий код, используя '\?' вместо просто '?' в операторе case (см. последние три закомментированные строки блока кода).

Есть ли конкретная причина, почему '?' сбежал? Я знаю, что любой символ может быть экранирован с помощью "\", но мой код работает отлично, без экранирования "?".

#!/bin/bash
while getopts ":abc" myopt; do
    case $myopt in
      [a-c])
       echo "$myopt is a valid option!" >&2
       ;;
      ?)
       echo "$OPTARG is an invalid option!" >&2
       ;;
     # \?)
     #  echo "$OPTARG is an invalid option!" >&2
     #  ;;
     esac
done

Для удобства прочтения этого кода ниже будет работать только если '?' сбежал (см. принятый ответ для хорошего объяснения).

#!/bin/bash 
while getopts ":abc" myopt; do
    case $myopt in
      \?)
       echo "$OPTARG is an invalid option!" >&2
       ;;

   [a-c])
       echo "$myopt is a valid option!" >&2
       ;;
    esac
done

если файл сценария - myscript.sh, его можно проверить следующим образом:

./myscript.sh -a -z -a  

1 ответ

Решение

Для Баш case заявление ? подстановочный знак, соответствующий любому одному символу / цифре. Если вы избежите этого с \? он конкретно пытается соответствовать '?' голец.

case будет продолжать находить совпадение, поэтому в этом случае, если переменная не [a-c] (a, b или c), тогда он будет совпадать, если переменная равна 1 символу.

Другие вопросы по тегам