Substituições de comandos vs escapes de barra invertida em uma string entre aspas

2

Considere uma substituição de comandos com aspas duplas com escapes de barra invertida dentro dela, assim:

echo "$(echo '\')"

Ela imprime \ , enquanto eu esperaria que ela imprimisse apenas uma barra invertida. Meu pensamento (que está incorreto) foi que ele passou por toda a string, substituindo todas as escapes de barra invertida, e então ele faria a substituição do comando. Evidentemente, a ordem é oposta.

No entanto, se fizermos

echo "$(echo '\')$"

imprime \$ . Eu teria esperado que, se estiver fazendo as substituições de comandos primeiro e, em seguida, avaliar que a barra invertida dessa string escape, que \ e $ possam se combinar para criar um único $ no final . Mas isso não acontece.

Onde os escapes de barra invertida se encaixam na ordem das coisas?

(O contexto para esta pergunta é que estou trabalhando em algo que irá escapar corretamente caracteres regex em uma string para inserção em um comando sed).

    
por AmadeusDrZaius 26.03.2015 / 04:44

3 respostas

2

Acho que é mais bem entendido pela saída de echo $(echo '\') (ou seja, uma variante sem as aspas externas), o que resulta em \ . O ponto é que não há nenhuma interpretação literal string das barras invertidas quando a entidade de substituição de comandos $(...) é expandida. (Isso é semelhante no caso de você ter caracteres de escape armazenados em strings; não haverá uma reinterpretação como uma string literal.)

    
por 26.03.2015 / 05:04
2

Em uma substituição de comando delimitada com $(…) , o que está dentro dos parênteses é analisado da mesma maneira que um comando de nível superior (exceto em alguns casos de canto envolvendo parênteses de fechamento desequilibrados). O que está dentro dos parênteses é um trecho de shell comum, não há nenhuma expansão de contrabarra adicional sendo feita.

O comando echo '\' imprime três caracteres: duas barras invertidas e uma nova linha (assumindo um comando echo que não faz expansão de barra invertida). Portanto, o resultado de uma substituição de comando $(echo '\') é a string de dois caracteres \ (a nova linha final é removida, a substituição de comando sempre faz isso). Como você usou a substituição de comandos dentro de aspas duplas, nenhuma outra expansão é executada: a parte da palavra resultante é \ .

Em echo "$(echo '\')$" , a substituição do comando gera uma única barra invertida. Sua contribuição para o argumento de echo é a string \ . O seguinte $ é seguido por um caractere que não pode iniciar um nome de parâmetro, portanto, ele se expande para si mesmo. Assim, o argumento para echo é a cadeia de dois caracteres \$ . As strings com aspas duplas não são mais expandidas, não há nada que possa fazer com que a barra invertida seja interpretada como um caractere especial (exceto alguns tipos do comando echo ).

Você pode procurar as regras de expansão completas nos manuais de shell e em outra documentação, com vários graus de (in) legibilidade. A especificação POSIX não é tão ruim quanto os padrões (louvor).

P.S. Como garantir que a string seja interpolada na substituição 'sed' escapa de todos os metacarismos

    
por 27.03.2015 / 02:47
1

Tem mais a ver com citações,

$ echo '\'
\
$ echo '\'
\
$ echo "\"
\

Com aspas simples, o que quer que esteja entre aspas é ecoado. Com aspas duplas, o shell olha para dentro e faz o processamento.

    
por 26.03.2015 / 11:07