Bash - какой смысл восстанавливать позиционные аргументы с помощью `set`? - PullRequest
2 голосов
/ 26 сентября 2019

Учитывая следующий код для разбора аргументов скрипта bash (скажем, example.sh):

#!/bin/bash
positional=()
while [ $# -gt 0 ]
do
    arg="$1"
    case ${arg} in
        -h|--help|\?)       show_usage;         exit 0      ;;
        -v|--verbose)       verbose=1;          shift       ;;
        -f|--file)          theFile="$2";       shift; shift;;
        *)                  positional+=("$1"); shift       ;;
    esac
done
set -- "${positional[@]}"

arg1a="${positional[0]}"; arg1b="$1" # same result, $arg1a == $arg1b
arg2a="${positional[1]}"; arg2b="$2" # same result, $arg2a == $arg2b

При следующем вызове скрипта:

./example.sh pos1 -v -f toto.txt pos2

  • До цикла "$1" == "pos1" и "$5" == "pos2"
  • После цикла до set --, $1, $2 и $5 не определены
  • После set --, "$1" == "pos1" и "$2" == "pos2"

Но также и после set --, ${positional[0]} == "pos1" и ${positional[1]} == "pos2".

Итак, вопросявляется: какова реальная точка использования set -- "${positional[@]}"?

Мы можем получить значения наших позиционных аргументов (с ${positional[i]}) в том же порядке, в котором они были предоставлены, не восстанавливая его до $1 и $2.Поэтому я не понимаю смысла использования set --.Если мы не используем его здесь, тогда $# -eq 0 и все ...

Пожалуйста, приведите реальный пример, где использование set -- обязательно, даже с этим массивом ${positional[]}.

1 Ответ

0 голосов
/ 27 сентября 2019

После цикла while массив 'positional' будет захватывать все параметры и аргументы командной строки, кроме '-v', '--verbose', '-f' и '--file' (и параметры в файл -f / -).

На этом этапе остальная часть сценария продолжит работать БЕЗ этих параметров.

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

Это может быть полезно, если скрипт выполнит другойкоманда (например, ls), которая не поддерживает параметры verbose / file, с предоставленными пользователем аргументами командной строки.

# Code to strip verbose/file command line options
while 
do
    ...
done
set --
# Do something above $verbose, $theFile
...
# Original script here - use any unprocessed parameters from command line
ls "$@"
...