В моем скрипте есть следующие команды:
set -- `getopt -q agvc:l:t:i: "$@"`
...
while [ -n "$1" ]
do
-i) TIME_GAP_BOOT=$2
shift ;;
...
sleep $TIME_GAP_BOOT
При вызове скрипта с помощью -i 2
я получаю ошибку
sleep: invalid time interval `\'2\''
Что я делаю не так? Как правильно оформить аргумент?
решение1
Встроенный bash getopts
гораздо проще в использовании. Если вы используете bash
, вам следует использовать его вместо getopt
.
GNU getopt
разработан для работы с аргументами, содержащими пробелы и другие метасимволы. Для этого он выдает строку результата с кавычками в стиле bash (или кавычками в стиле csh, в зависимости от опции -s
.) Вам нужно организовать интерпретацию кавычек, что требует использования eval
. (Я уже говорил, что встроенная функция bash getopts
лучше?).
Следующий пример взят из дистрибутива getopt; я не имел к нему никакого отношения. (Он должен присутствовать где-то на вашей машине; в Ubuntu и Debian он отображается как /usr/share/doc/util-linux/examples/getopt-parse.bash
. Я только цитирую несколько строк:
# Note that we use `"$@"' to let each command-line parameter expand to a
# separate word. The quotes around `$@' are essential!
# We need TEMP as the `eval set --' would nuke the return value of getopt.
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
-n 'example.bash' -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
Помимо цитат, на которые указывает комментарий к примеру, важно обратить внимание на eval
, который обычно не одобряется.
В отличие от этого, встроенная функция bash getopts
не требует eval
, и она довольно проста; она по сути эмулирует стандартный вызов библиотеки C:
while getopts agvc:l:t:i: opt; do
case "$opt" in
i) TIME_GAP_BOOT=$OPTARG;;
# ...
esac
done