Вопрос или проблема
Вот мой test.sh
:
#!/usr/bin/env bash
arg="default"
TEMP=$(getopt --long been: -n 'test.sh' -- "$@")
eval set -- "$TEMP"
while true ; do
case "$1" in
--been)
echo 'в опции been'
arg="$2"
shift;;
--)
echo 'в конце'
shift ; break ;;
esac
done
echo "$arg"
Присвойте значение arg
:
bash ./test.sh --been=xxyyzz
в конце
default
Почему не получается получить результат>?
bash ./test.sh --been=xxxx
в опции been
xxxx
В manpage
для getopt(1)
упоминается, в разделе BUGS,
Синтаксис, если вы не хотите никаких коротких переменных опций, не очень интуитивен (вам нужно явно установить их в пустую строку).
Поэтому вам нужно
getopt --long been: -n test.sh "" "$@"
(Если вы хотите включить --
в аргументы getopt
, он должен быть до этого пустого аргумента)
С этим изменением,
в опции been
xxyyzz
(Вам также нужен break
в секции case
для --been
, и нужно использовать shift 2
, чтобы избавиться от аргумента)
.
Ответ или решение
Ваша проблема с присвоением значения переменной при использовании команды getopt
в Bash является распространенной ошибкой, связанной с неверным использованием этой команды и её параметров. Давайте разберем, что происходит и как это исправить.
Объяснение проблемы
В вашей скрипт test.sh
, вы определяете переменную arg
со значением "default", но не получаете ожидаемого результата при вызове скрипта через bash ./test.sh --been=xxyyzz
. Суть проблемы заключается в следующем:
-
Синтаксис команды
getopt
: Ваша текущая командаgetopt --long been: -n 'test.sh' -- "$@"
неправильно обрабатывает аргументы, поскольку нет явного указания на отсутствие коротких опций.getopt
ожидает, что все аргументы будут соответствовать его формату. -
Отсутствие аргумента: Когда вы вызываете
getopt
, значения после--been
(например,xxyyzz
) считаются отдельными аргументами, но так как вы не указали пустую строку как первый аргумент вgetopt
, это приводит к тому, что значение не передается должным образом.
Решение проблемы
Чтобы исправить вашу ошибку, вы должны внести следующие изменения:
-
Добавьте пустой аргумент: Измените вызов
getopt
, добавив пустую строку перед"$@"
:TEMP=$(getopt --long been: -n 'test.sh' "" -- "$@")
-
Используйте
shift 2
: После того как вы указалиarg="$2"
внутри блокаcase
для--been
, добавьтеshift 2
вместоshift
, чтобы сдвинуть на два аргумента (ключ и значение):case "$1" in --been) echo 'in been option' arg="$2" shift 2;;
-
Разместите
break
: Убедитесь, чтоbreak
находится послеshift
в блокеcase
, чтобы корректно завершить цикл после обработки параметров.
Полный исправленный скрипт
Теперь ваш скрипт будет выглядеть следующим образом:
#!/usr/bin/env bash
arg="default"
TEMP=$(getopt --long been: -n 'test.sh' "" -- "$@")
eval set -- "$TEMP"
while true ; do
case "$1" in
--been)
echo 'in been option'
arg="$2"
shift 2;;
--)
echo 'in the end'
shift; break;;
esac
done
echo "$arg"
Проверка скрипта
Теперь, если вы выполните:
bash ./test.sh --been=xxyyzz
Ожидаемый вывод будет:
in been option
xxyyzz
Заключение
Ваша проблема возникла из-за неправильного использования параметров в команде getopt
, что привело к неправильной интерпретации ваших аргументов. После исправлений скрипт будет работать корректно, и вы сможете успешно присваивать значения переменным. Если у вас возникнут дополнительные вопросы по использованию getopt
, не стесняйтесь спрашивать.