Como escapar de aspas com casca?

65

Estou tendo problemas para escapar de caracteres no bash. Eu gostaria de escapar de aspas simples e duplas ao executar um comando com um usuário diferente. Para os fins desta pergunta, digamos que eu queira ecoar o seguinte na tela:

'single quote phrase' "double quote phrase"

Como posso escapar de todos os caracteres especiais, se eu também precisar mudar para um usuário diferente:

sudo su USER -c "echo \"'single quote phrase' \"double quote phrase\"\""

Obviamente, isso não produz o resultado certo.

m33lky
fonte
+1 em "Obviamente, isso não produz os resultados corretos". bashestá a caminho de me deixar louco.
Rolf

Respostas:

88

Você pode usar a seguinte sintaxe literal de cadeia de caracteres:

> echo $'\'single quote phrase\' "double quote phrase"'
'single quote phrase' "double quote phrase"

De man bash

Palavras da forma $ 'string' são tratadas especialmente. A palavra se expande para cadeia, com caracteres de escape com barra invertida substituídos conforme especificado pelo padrão ANSI C. Seqüências de escape de barra invertida, se presentes, são decodificadas da seguinte maneira:

          \a     alert (bell)
          \b     backspace
          \e
          \E     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \'     single quote
          \"     double quote
          \nnn   the eight-bit character whose value is the octal value nnn (one to three digits)
          \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
          \cx    a control-x character
SiegeX
fonte
5
Exagero. Na maioria dos casos, você não precisa usar a sintaxe literal de cadeia de caracteres.
precisa saber é o seguinte
Mais detalhes aqui stackoverflow.com/a/16605140/149221
mj41 28/04
12

Em um shell POSIX, supondo que na sua string não haja expansão de variável, comando ou histórico e não haja nova linha, siga estas prescrições básicas:

  1. Para citar uma sequência genérica com aspas simples, execute as seguintes ações:

    1. Substitua qualquer sequência de caracteres sem aspas simples pela mesma sequência por aspas simples iniciais e finais adicionadas: 'aaa' ==> ''aaa''

    2. Escape com uma barra invertida todos os caracteres de aspas simples preexistentes : ' ==> \'
      Em particular,''aaa'' ==> \''aaa'\'

  2. Para citar uma sequência genérica com aspas duplas, execute as seguintes ações:

    1. Adicione aspas duplas à esquerda e à direita: aaa ==> "aaa"

    2. Escape com uma barra invertida todos os caracteres de aspas duplas e todos os caracteres de barra invertida: " ==> \", \ ==> \\

Alguns exemplos:

''aaa""bbb''ccc\\ddd''  ==>  \'\''aaa""bbb'\'\''ccc\\ddd'\'\'
                        ==>  "''aaa\"\"bbb''ccc\\\\ddd''"

para que seu exemplo possa ser expandido com o seguinte:

#!/bin/sh

echo \''aaa'\'' "bbb"'
echo "'aaa' \"bbb\""

sudo su enzotib -c 'echo \'\'\''aaa'\''\'\'\'' "bbb"'\'
sudo su enzotib -c 'echo "'\''aaa'\'' \"bbb\""'

sudo su enzotib -c "echo \\''aaa'\\'' \"bbb\"'"
sudo su enzotib -c "echo \"'aaa' \\\"bbb\\\"\""
enzotib
fonte
10

Exemplo simples de escape de aspas no shell:

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

Isso é feito finalizando um já aberto ( '), colocando um escapado ( \') e depois outro ( ').

Alternativamente:

$ echo 'abc'"'"'abc'
abc'abc
$ echo "abc"'"'"abc"
abc"abc

Isso é feito finalizando já aberto um ( '), colocando aspas em outro aspas ( "'") e abrindo outro ( ').

Relacionado: Como escapar de aspas simples em strings de aspas simples? no stackoverflow SE

kenorb
fonte
1

A resposta aceita funciona para citações simples (um nível):

$ echo $'\'single quote phrase\' "double quote phrase"'
'single quote phrase' "double quote phrase"

Para que o comando seja apresentado, você precisa citar duas vezes.
Este script pode fazer todo o trabalho:

#!/bin/bash

quote () { 
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}

read -r line <<-\_line_to_quote_
'single quote phrase' "double quote phrase"
_line_to_quote_

quote "$line"; echo
quote "echo $(quote "$line")"; echo

Execute o script para obter:

$ script
''\''single quote phrase'\'' "double quote phrase"'
'echo '\'''\''\'\'''\''single quote phrase'\''\'\'''\'' "double quote phrase"'\'''

A primeira linha funciona para eco simples:

$ echo ''\''single quote phrase'\'' "double quote phrase"'
'single quote phrase' "double quote phrase"

A segunda linha funcionará para o comando de aspas duplas:

sudo su USER -c 'echo '\'''\''\'\'''\''single quote phrase'\''\'\'''\'' "double quote phrase"'\'''

fonte
-3

eco 'eu sou aluno' não funciona. Mas o seguinte funciona:

echo $ 'eu sou aluno' Na página de manual do bash:

Uma aspas simples pode não ocorrer entre aspas simples, mesmo quando precedida por uma barra invertida. .... Palavras da forma $ 'string' são tratadas especialmente. A palavra se expande para cadeia, com caracteres de escape com barra invertida substituídos conforme especificado pelo padrão ANSI C.

Sarf
fonte
6
Isso não adiciona nada às respostas existentes.
jasonwryan