Bash - O parâmetro não deve ser analisado como bash durante a saída

1

Eu tenho 2 Scripts Shell. O primeiro aciona o segundo e adiciona alguns parâmetros. O segundo chama um comando e adiciona os parâmetros do primeiro script como parâmetros para o comando.

O primeiro se parece com algo como:

#!/usr/bin/env bash

ADDITIONAL_ARGUMENTS='--set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"'

SUPER_PARAMS=${ADDITIONAL_ARGUMENTS} my_second_script.sh

Então, o segundo script faz algo como:

#!/usr/bin/env bash

randomBinary --some-hardcoded-parameters \
             "${SUPER_PARAMS}"

O que eu esperaria ter é uma saída de:

randomBinary --some-hardcoded-parameters --set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"

Mas, em vez disso, a chamada parece:

randomBinary --some-hardcoded-parameters '--set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"'

Eu tentei dois dias citando o parâmetro corretamente, mas sem resultados.

    
por David Lambauer 08.12.2017 / 11:46

2 respostas

3

Para armazenar vários argumentos, use uma matriz, não uma variável escalar.

additional_arguments=(
  --set
  'args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}'
)
randomBinary --some-hardcoded-parameters "${additional_arguments[@]}"

Note que como as variáveis de ambiente são strings de bytes não-NUL, você precisa de alguma codificação se quiser passar uma definição de array para outro comando através do ambiente.

Com ksh , bash , zsh ou yash , você pode usar:

ARRAY_DEFINITION="$(typeset -p additional_arguments)" my_second_script.sh

para exportar a definição da matriz em uma variável de ambiente no script de chamada.

E eval "$ARRAY_DEFINITION" no script chamado para importar essa definição de matriz.

Note que é importante que o código seja avaliado no mesmo local e com o mesmo shell em que foi gerado.

Observe também que, se a definição da matriz for avaliada dentro de uma função, a matriz será local para a função.

Alguns shells como rc , es ou fish permitem exportar matrizes (usando sua própria codificação internamente).

Aqui, seria mais fácil passar as informações como argumentos para o script chamado, já que esse é um array.

No script de chamada:

my_second_script.sh "${additional_arguments[@]}"

No script chamado:

randomBinary --some-hardcoded-parameters "$@"

Ou chame o script chamado com . para compartilhar as variáveis do shell do responsável pela chamada para que você não precise usar o ambiente para passar esses dados por uma execução.

    
por 08.12.2017 / 14:37
0

Aqui,

randomBinary --some-hardcoded-parameters "${SUPER_PARAMS}"

SUPER_PARAMS contém --set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}" e, como é citado, é passado como está. Se fosse sem aspas, seria dividido em espaços em branco para as cinco strings --set , "args={/bin/bash,-c,cd , /var/www , && , sudo -u www-data bash scripts/system/update.sh}" e essas seriam passadas como argumentos.

Parece que você quer que as aspas dentro da variável também sejam interpretadas, e isso requer a adição de outra camada de análise de shell, com eval ou executando a coisa através de bash -c '...'

O script de teste aqui:

$ cat test.sh
#!/bin/bash    
ARGS='--set "args={this, that && that}"'
./args.sh $ARGS
eval "./args.sh $ARGS"

impressões:

<!-- language: lang-none -->
$ bash test.sh
5 args: <--set> <"args={this,> <that> <&&> <that}"> 
2 args: <--set> <args={this, that && that}> 

(O script args.sh imprime o número é o número de argumentos distintos e os próprios argumentos são impressos em <...> )

Observe que o eval executará, e. qualquer substituição de comando, então ele abre a execução de código arbitrário. Normalmente, seria melhor manter os argumentos em um array de shell , mas aqui você os está transmitindo de um script para outro, então isso não funciona muito bem. Veja a seção "Como eu armazeno um comando em uma variável?" em esta resposta sobre como lidar com espaços em branco .

Além disso, Divisão do Word no Guia de Bash , você também pode usar set -x para ver quais comandos o shell realmente executa.

    
por 08.12.2017 / 14:37