Что означает $ {@: 2} в сценариях оболочки

27

Я вижу это в сценарии оболочки.

variable=${@:2}

Что это делает?

Ленин Радж Раджасекаран
источник
Это именно так, как это показано в сценарии? Синтаксис выглядит как массив, но в нем отсутствуют некоторые фрагменты. Можете ли вы опубликовать пару строк вокруг этой строки из сценария?
СЛМ
Это переменная, начиная со второй буквы. var="my_value"; echo var="${var[@]:2}"; echo "$var"Увидеть разницу?
Валентин Байрами

Ответы:

34

Он показывает содержимое специальной переменной $@в Bash. Он содержит все аргументы командной строки, и эта команда принимает все аргументы со второго на и хранить их в переменной variable.

пример

Вот сценарий экзамена.

#!/bin/bash

echo ${@:2}

variable=${@:3}
echo $variable

Пример выполнения:

./ex.bash 1 2 3 4 5
2 3 4 5
3 4 5

Ссылки

SLM
источник
9
Обратите внимание, что показанная техника объединяет данные аргументы в одну строку. Если вам нужно хранить их как отдельные аргументы, используйте массив:vars=( "${@:2}" )
glenn jackman
@glennjackman - спасибо, что указал на это.
SLM
2
Также обратите внимание на использование фигурных скобок. Предполагается, что вы всегда используете фигурные скобки, но Bash позволяет вам их опускать, когда контекст однозначен. Поэтому $@и ${@}идентичны, хотя последний имеет «более правильный» синтаксис. Вы должны использовать скобки с ${@:2}, потому что $@:2это неоднозначно и поэтому будет интерпретироваться как ${@}:2, что не одно и то же.
Пэдди Ландау
14

Эта kshфункция также встречается в bashпоследних версиях zsh.

В kshи bashвы можете получить доступ к нескольким элементам массива, используя ${array[@]:first:length}синтаксис, который расширяет до length(или все, если lengthне указано) элементов arrayмассива (в списке элементов массива, отсортированных по номерам по индексам), начиная с первый с индексом, большим или равным first. В скалярном контексте (как здесь в присваивании скалярной переменной) список элементов объединяется с пробелами с bashи ksh93и с первым символом $IFS(или ничего, если $IFSпусто или пробел, если не установлено) с zsh.

Например:

$ a[23]=a a[5]=b a[235]=c a[45]=d
$ x=${a[@]:12:2}; printf '<%s>\n' "$x"
<a d>

$@это особый случай. $@массив позиционных параметров ( $1, $2...). Но при использовании с :, $0также включен. Так ${@:1}же, как $@и не ${@:0}для других массивов.

Во zsh, это немного отличается. zshДобавлен kshсинтаксис только недавно для совместимости, но есть собственный синтаксис для выбора диапазонов элементов.

В отличие от kshи bash, zshмассивы являются типом переменной, отличным от скалярных переменных, не разрежены ( zshимеет ассоциативные массивы в качестве другого типа переменной) и начинаются с индекса 1 вместо 0.

Для zsh, вы получаете доступ к диапазонам элементов массива с помощью $a[first,last](где lastтакже может быть отрицательным для обратного отсчета от конца).

В zsh,

a[23]=a a[5]=b a[235]=c a[45]=d

создает массив из 235 элементов, большинство из которых пустые. $a[12,50]будет расширяться до элементов с 12 по 50, и ${a[@]:12:2}будет расширяться только до (пусто) $a[12]и $a[13]элементов. Как особый случай, и опять же для переносимости с ksh93и bash, zshтакже принимает 0первый элемент для $@и обрабатывает это как $0.

Таким образом, вы можете использовать ${a[@]:x:n}и ${@:x:n}для всех трех оболочек, но только для не разреженных массивов, и обратить внимание на значение IFS.

Стефан Шазелас
источник