getopts не работает, когда есть аргументы перед опциями - PullRequest
0 голосов
/ 08 ноября 2018

Когда я запускаю команду так:

$: ./script -r f1 f2:
он обнаруживает флаг "-r" и устанавливает рекурсивный флаг в 1.

$: ./script directory/ -r:
getopts вообще не обнаруживает флаг -r. Таким образом, внутри оператора case он никогда не обнаружит флаг -r, поэтому цикл while даже не запускается вообще. как это исправить?

RECURSIVE_FLAG=0
while getopts ":rR" opt ; do
    echo " opt = $opt"
    set -x
    case "$opt" in 

        r) RECURSIVE_FLAG=1 ;;
        R) RECURSIVE_FLAG=1 ;;
        :)echo "not working" ;;
        *)echo "Testing *" ;;

    esac
done

1 Ответ

0 голосов
/ 08 ноября 2018

Это не имеет ничего общего с косой чертой. getopts останавливает обработку параметров, когда доходит до первого аргумента, который не начинается с -. Это задокументированное поведение:

Когда встречается конец опций, getopts завершается с возвращаемым значением больше нуля. OPTIND устанавливается в качестве индекса первого неопционального аргумента, а name устанавливается в ?.

Ваше утверждение, что оно работает при использовании

./script f1 f2 -r

просто неправильно. Я добавил echo $RECURSIVE_FLAG в конец вашего скрипта, и когда я запустил его таким образом, он повторил 0.

Если вы хотите разрешить более либеральный синтаксис, с опциями после имен файлов (например, GNU rm), вам нужно выполнить собственный анализ аргументов. Поместите вашу петлю getopts в другую петлю. Когда цикл getopts заканчивается, вы можете сделать:

# Find next option argument
while [[ $OPTIND <= $# && ${!OPTIND} != -* ]]; do
    ((OPTIND++))
done
# Stop when we've run out of arguments
if [[ $OPTIND > $# ]]; then
    break
fi
...