Problema com argumentos parametrizados de escape

2

Eu me sinto realmente relutante em fazer essa pergunta, pois parece que estou sentindo falta de algo realmente óbvio. No entanto, não consigo encontrar perguntas existentes com exatamente o mesmo problema.

Temos um script que não devemos editar e está causando um problema em como ele está lidando com argumentos que incluem espaço em branco. Reduzi o problema para um caso reproduzível muito simples:

Primeiro, criei um script simples que mostra os argumentos de linha de comando passados para ele:

#!/bin/bash
for i; do
    echo $i
done

Em seguida, defino uma variável de ambiente que será passada para a linha de comando

MYOPT="With Space"

Então, e essa é a parte que não consigo alterar em nosso ambiente, chamo o comando usando a variável como um parâmetro. Infelizmente, a variável não é citada em nosso ambiente.

./mycommand.sh $MYOPT

A saída disso é, como você esperaria,

./mycommand.sh $MYOPT
"With
Space"

Se você citar a variável no comando acima, isso funciona. Essa parece ser a solução geralmente aceita para esse problema quando se olha para outras questões similares.

./mycommand.sh "$MYOPT"
"With Space"

No entanto, como mencionei, não podemos alterar como esse script é chamado.

Eu tentei adicionar aspas extras na variável de ambiente da seguinte forma, mas isso também não ajudou:

MYOPT="\"With Space\""
./mycommand.sh $MYOPT
"With
Space"

Existe uma maneira de definir essa variável de ambiente com espaços de forma que ela possa ser passada para um script sem citá-la na invocação?

Para aqueles que estão interessados, este problema está se apresentando em nosso ambiente tomcat RHEL7. JAVA_OPTS está definido em tomcat.conf e nós temos -Dparamaters="with spaces". O script de controle principal que acompanha o Tomcat não cita esses JAVA_OPTS quando chama Java, o que leva a esse problema. Reduzi o problema para o exemplo simples acima.

    
por Tom17 09.05.2017 / 22:50

1 resposta

2

Você não pode voltar de ./mycommand.sh $MYOPT para o valor de MYOPT . É por isso que você não encontrou uma maneira de fazer isso: é impossível. mycommand.sh não recebe informações suficientes para reconstruir o valor original.

Por exemplo, se o valor de MYOPT for * , então mycommand.sh será chamado com a lista de nomes de arquivos no diretório atual. Não tem como saber como essa lista foi construída.

Se você sabe que o valor de MYOPT segue determinadas regras , talvez seja possível reconstruí-lo. A versão simples dessas regras é:

  • O valor não contém nenhum dos caracteres \[*? ou guia ou nova linha.
  • O valor não inicia nem termina com um espaço e não contém espaços consecutivos.

De acordo com essas suposições, "$*" in mycommand.sh fornecerá o valor de MYOPT . Mas tenha em mente que isso não pode funcionar em geral.

A solução adequada é consertar seu ambiente. Na linguagem de shell, $MYOPT não significa "pegue o valor de MYOPT ", isso significa "pegue o valor de MYOPT , divida-o de acordo com o valor de IFS e trate cada parte resultante como padrão curinga que é expandido se corresponder a pelo menos um arquivo ”. A maneira de escrever "pegue o valor de MYOPT " é "$MYOPT" ou, mais geralmente, use $MYOPT entre aspas duplas .

    
por 10.05.2017 / 01:44