Рассмотрим следующий сценарий, который я упростил из этого вопроса.
#!/bin/bash
A=( foo bar "a b c" 42 )
B=("${A[@]:1}") # slice to the end of the array
echo "${B[@]}"
Это работает нормально, но если я попытаюсь использовать аналогичный синтаксис для массива аргументов $@, я получу синтаксическую ошибку:
#!/bin/bash
echo "$@"
B=("${$@:1}") # slice to the end of the array
Выполнение:
./play x y z
./play: line 4: ${$@:1}: bad substitution
Есть ли другой магический синтаксис для разрезания массива аргументов?
Вы не пишете $ дважды, когда пишете ${A[@]:1}, как вы думаете, почему вам нужно сделать это дважды для @?
Также смотрите Bash: фрагмент позиционных параметров.
На самом деле вы можете использовать команду shift для смещения аргументов.
Я знаю о shift, но у меня были другие причины не изменять исходный массив аргументов. В частности, я использовал exec для повторных попыток.



Небольшое изменение формата:
$ cat play
echo "$@"
B=( "${@:1}" )
typeset -p B
Берем на тест-драйв:
$ ./play x y z
x y z
declare -a B=([0] = "x" [1] = "y" [2] = "z")
Нужно учитывать, что 0-я позиция ($0) — это имя скрипта:
B=( "${@:0}" )
typeset -p B
=> declare -a B=([0] = "./play" [1] = "x" [2] = "y" [3] = "z")
Итак, вам нужно сдвинуть позицию на единицу вправо (т. е. изменить 1 на 2):
$ cat play
echo "$@"
B=( "${@:2}" )
typeset -p B
Берем на тест-драйв:
$ ./play x y z
x y z
declare -a B=([0] = "y" [1] = "z")
Возможно, вам захочется
"${@:2}". Это описано с примерами в Справочном руководстве Bash.