Quantos níveis de indireção posso aplicar no Bash?

2

No bash, eu entendo que podemos ter uma expansão indireta variável de duas formas:

  • Usando declare : declare -n foo=bar
  • Usando a expansão ${!..} .

Podemos combinar os dois:

declare -n foo=SHELL
bar=foo
echo ${!bar}

dá:

/bin/bash

É possível estender isso para mais níveis?

É principalmente como escrever código ofuscado - alguns dos meus amigos estão se desafiando.

    
por avidenat 21.11.2018 / 14:30

2 respostas

0

Na verdade, existe um método adicional para fazer as indirecções no Bash, pelo menos de forma eficaz: Se tiver a=1 e b=a , pode obter o valor de a a b da seguinte forma:

eval echo \${$b}

Isso pode ser aninhado várias vezes:

$ a=1; b=a; c=b; d=c
$ eval eval eval echo \\\\${\\${\${$d}}}
1

Aqui estão as regras para encontrar o número certo de barras invertidas em cada nível:

  1. No nível mais interno, nenhuma barra invertida é usada.
  2. Em qualquer outro nível, use 2 n + 1 barras invertidas, onde n é o número de barras invertidas que são usadas no próximo nível interno.

Justificativa: A regra 1 é trivial. Regra 2 vem do fato de que você tem que aplicar mais uma barra invertida no próximo nível interno, enquanto você tem que escapar de todos aqueles que não são consumidos no nível atual, ou seja, todos menos um.

Como consequência, o número de barras invertidas necessárias diverge exponencialmente com o aumento do número de níveis, de modo que o aninhamento atinge seu limite em breve para esse método.

Mas é preciso enfatizar aqui que esse limite é de natureza bastante acadêmica. Na prática, quando se tem que respeitar necessidades como manutenção, normalmente não se quer lidar com mais do que dois ou três níveis de indireção em uma única expressão - não importa qual método de indireção seja usado.

Em vez disso, pode-se resolver níveis mais altos de indireção usando um loop para iterar algo como

value=${variable}
variable=${!value}

um número de vezes que é adequado para a aplicação dada.

    
por 25.11.2018 / 16:13
0

Há uma indireta (grande) permitida diretamente na expansão aritmética para apenas números .

$ a=123 b=a c=b d=c e=d ; echo $((e))
123

você pode expandi-lo com declare:

$ jj=123; for ii in {a..f}{a..z}; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
123

Mas não é infinito:

$ jj=123; for ii in {a..z}{a..z}; do declare $ii=$jj; jj=$ii; done; echo "$((ii))"
bash: tz: expression recursion level exceeded (error token is "tz")

Isso é suficiente?

    
por 25.11.2018 / 22:53