Como evitar que a saída de substituição do comando bash seja escapada?

6

Estou tentando usar a substituição de comando em um script bash para gerar símbolos de redirecionamento com base em uma variável da seguinte forma:

IS_VERBOSE=false
curl $BLAH $( $IS_VERBOSE && echo '-i' || echo '> /dev/null' )

Ou seja, se verboso, adicione a opção -i , caso contrário, lance tudo de stdout afastado. O problema é que quando IS_VERBOSE é falso, meu comando se torna

curl $BLAH \> /dev/null

Geralmente, a substituição de comandos escapa dos caracteres > >> & | # $ e possivelmente de outros. Como posso produzir esses símbolos sem escapar usando a substituição de comandos?

    
por asmodean 15.10.2015 / 17:26

3 respostas

5

Depois que a subestixação acontece (qual BTW no POSIX só poderia ter como alvo o lado esquerdo antes de qualquer ">"), não há mais avaliação sobre se existe algum ">" então a abordagem que você imaginou não funcionaria.

Se você não se preocupa com a conformidade POSIX (afinal você marcou isso como 'bash') você ainda pode encontrar uma solução, definindo dinamicamente o lado direito, mas eu pessoalmente optaria por uma abordagem totalmente diferente; dê uma olhada no seguinte post detalhando um modo detalhado / silencioso com base em descritores de arquivos personalizados: link .

Um trecho de código desse post para mostrar como seria bom:

# Some confirmations:
printf "%s\n" "This message is seen at verbosity level 3 and above." >&3
printf "%s\n" "This message is seen at verbosity level 4 and above." >&4
printf "%s\n" "This message is seen at verbosity level 5 and above." >&5
    
por 15.10.2015 / 18:33
3

Eu sei que isso não está resolvendo o seu problema de escape (que eu não tenho certeza ainda é possível), mas vindo de man curl , isso alcançaria o que você está tentando fazer:

BLAH=localhost

IS_VERBOSE=true
OPTIONS="-o /dev/null"
$IS_VERBOSE && OPTIONS=""

curl $BLAH -s $OPTIONS
    <html>
    <p>hi</p>
    </html>

IS_VERBOSE=false
OPTIONS="-o /dev/null"
$IS_VERBOSE && OPTIONS="-i"

curl $BLAH -s $OPTIONS

O segundo não produz nada. E é menos dependente de diferentes shells (bash, sh, etc), então mais portável.

    
por 15.10.2015 / 18:25
2

de acordo com o manual bash, a ordem das expansões de shell é expansão de chave, expansão de til, expansão de parâmetro e variável, substituição de comando, expansão aritmética, divisão de palavras e expansão de nome de caminho . Também é afirmado que os redirecionamentos acontecem antes do comando ser executado - ou seja, após a expansão do shell. Assim, vem a razão que comandos como:

redir='>'
echo value $redir file

e

echo value $(echo '>') file

colocaria valor no arquivo arquivo .

Infelizmente, este não é o caso porque a linha de comando é primeiramente analisada e os tokens de redirecionamento são apenas identificados neste estágio. Posteriormente, antes de o comando ser executado, os redirecionamentos são realizados com base nesses tokens.

eval curl $BLAH $( $IS_VERBOSE && echo '-i' || echo '> /dev/null' )

funciona analisando novamente o comando, assim identifica os redirecionamentos, mas também executa a expansão do shell, o que é um pouco complicado de se trabalhar, e pode levar a um comportamento inesperado.

nota: há tratamento especial no bash para >$var e >&$var

    
por 15.10.2015 / 21:46