Expansão do parâmetro Bash

1

Eu li / foi informado que no Bash (4+ no meu caso) que todas as funções de expansão de parâmetro que estão disponíveis em strings estão disponíveis em matrizes. Hoje eu estava tentando configurar uma função semelhante a um array pop. Eu usei algo semelhante à seguinte sintaxe:

declare -a arr=( 0 1 2 3 4 5 )
arr=( ${arr[@]:0:(-1)} )

Inesperadamente, Bash reclamou com:

-bash: (-1): substring expression < 0

Quando faço isso com uma string, a sintaxe funciona como esperado. Por exemplo:

var="see spot run"
var="${var:0:(-1)}"
echo "$var"
  see spot ru

Eu sei que para o array eu poderia fazer isso (e eu testei que funciona):

declare -a arr=( 0 1 2 3 4 5 )
arr=( ${arr[@]:0:((${#arr[@]}-1))} )
echo ${arr[@]}
    0 1 2 3 4

As perguntas são se todas as expansões de parâmetro de string funcionam em matrizes, por que a sintaxe (-1) não funciona como eu esperava? Estou apenas procurando algo simples aqui ou há algo mais profundo em jogo que eu estou perdendo?

    
por EnterUserNameHere 20.11.2018 / 13:09

1 resposta

2

A resposta a essa pergunta parece ser que nem todas as expansões de parâmetros de string funcionam em matrizes. Depois de revisar os comentários e ler o Manual de Referência do Bash (link fornecido por don_crissti, obrigado), há uma advertência para a indexação negativa na expansão da substring. Conforme observado no manual do Bash ( Expansão do Parâmetro do Shell ):

${parameter:offset:length}

This is referred to as Substring Expansion. It expands to up to length characters of the value of parameter starting at the character specified by offset. If parameter is @, an indexed array subscripted by @ or *, or an associative array name, the results differ as described below.

...

If parameter is an indexed array name subscripted by @ or *, the result is the length members of the array beginning with ${parameter[offset]}. A negative offset is taken relative to one greater than the maximum index of the specified array. It is an expansion error if length evaluates to a number less than zero.

Como apontado por don_crissti, a avaliação de comprimento que é feita aqui não está em referência ao comprimento da string / substring, mas sim à avaliação realizada durante a atribuição do atributo length. Como no exemplo de don_crissti:

a=2
printf %s\n "${arr[@]:3:(a+1)}"

Se a porção de avaliação aritmética da atribuição de comprimento (a + 1) resultasse em um valor negativo ou, como no meu caso, o valor em si fosse estaticamente passado como um número negativo, seria um erro de expansão. Dito isto, ambos os itens a seguir resultariam em um erro de expansão:

declare -a arr=( 0 1 2 3 4 5 )
# length evaluates to (-1)
a=2
printf %s\n "${arr[@]:3:(a-3)}"
  -bash: (a-3): substring expression < 0

# or length is assigned as (-1)
arr=( ${arr[@]:0:(-1)} )
  -bash: (-1): substring expression < 0

De acordo com o manual de Bash, esse é o comportamento esperado em ambos os casos.

    
por 21.11.2018 / 12:36

Tags