O que esse $ {@: 2} significa em scripts de shell

27

Eu vejo isso em um script de shell.

variable=${@:2}

O que isso está fazendo?

Lenin Raj Rajasekaran
fonte
Foi exatamente assim que apareceu no script? A sintaxe parece uma matriz, mas faltam algumas partes. Você pode postar algumas linhas ao redor desta linha a partir do script?
slm
Essa é uma variável que começa na segunda letra. var="my_value"; echo var="${var[@]:2}"; echo "$var"Veja a diferença?
Valentin Bajrami

Respostas:

34

Está mostrando o conteúdo da variável especial $@, no Bash. Ele contém todos os argumentos da linha de comando e este comando está pegando todos os argumentos do segundo e os armazenando em uma variável variable.

Exemplo

Aqui está um script de exemplo.

#!/bin/bash

echo ${@:2}

variable=${@:3}
echo $variable

Exemplo de execução:

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

Referências

slm
fonte
9
Observe que a técnica mostrada mistura os argumentos fornecidos em uma única sequência. Se você precisa mantê-los como argumentos separados, usar uma matriz:vars=( "${@:2}" )
Glenn Jackman
@glennjackman - obrigado por apontar isso.
slm
2
Observe também o uso dos colchetes. Você sempre deve usar colchetes, mas o Bash permite omiti-los quando o contexto é inequívoco. Portanto, $@e ${@}são idênticos, embora o último seja a sintaxe "mais correta". É necessário usar os colchetes com ${@:2}, porque $@:2é ambíguo e, portanto, seria interpretado como ${@}:2, o que não é a mesma coisa.
Paddy Landau
14

Esse é um kshrecurso também encontrado nas bashversões recentes do zsh.

Em kshe bash, você pode acessar vários elementos de uma matriz usando a ${array[@]:first:length}sintaxe, que se expande para até length(ou todos, se lengthfor omitido) elementos da arraymatriz (na lista de elementos da matriz classificados numericamente nos índices), começando com o primeiro com índice maior ou igual a first. Quando no contexto escalar (como aqui em uma atribuição a uma variável escalar), a lista de elementos é unida com caracteres de espaço com bashe ksh93e com o primeiro caractere de $IFS(ou nada se $IFSestiver vazio ou espaço se não estiver definido) com zsh.

Por exemplo:

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

$@é um caso especial. $@é a matriz de parâmetros posicionais ( $1, $2...). Mas quando usado com :, $0também está incluído. Assim ${@:1}é o mesmo que $@, não ${@:0}como para outras matrizes.

Em zsh, é um pouco diferente. zshadicionou a kshsintaxe apenas recentemente para compatibilidade, mas tem sua própria sintaxe para selecionar intervalos de elementos.

Ao contrário de kshe bash, zshmatrizes são um tipo de variável diferente das variáveis ​​escalares, não são esparsas ( zshtem matrizes associativas como outro tipo de variável) e iniciam no índice 1 em vez de 0.

Para zsh, você acessa intervalos de elementos de matriz com $a[first,last](onde lasttambém pode ser negativo para contar de trás para frente no final).

Em zsh,

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

cria uma matriz com 235 elementos, a maioria deles vazios. $a[12,50]iria expandir-se para elementos 12-50, e ${a[@]:12:2}só iria expandir-se para o (vazio) $a[12]e $a[13]elementos. Como um caso especial, e novamente para portabilidade com ksh93e bash, zshtambém aceita um 0primeiro elemento $@e trata isso como $0.

Portanto, você pode usar ${a[@]:x:n}e ${@:x:n}portável em todas as três conchas, mas apenas para matrizes não esparsas, e prestar atenção ao valor do IFS.

Stéphane Chazelas
fonte