Evite escapar de aspas duplas

2

Eu tenho alguns comandos que quero executar em um script bash.
Agora, quando usamos aspas simples, a variável é considerada literal e não o valor.
Então fazendo, por exemplo ls "$SOME_DIR" não é o mesmo que ls '$SOME_DIR'
Como podemos lidar com uma mistura de aspas e aspas duplas de uma forma que nem tudo é confuso com aspas duplas de escape?
Por exemplo. como validar algo como:

ssh server.com "mkdir \"/foo/bar/"$final"\""  

Como posso evitar todas essas fugas já que quanto mais tempo os comandos se tornam ilegíveis e muito fáceis de quebrar?

    
por Jim 16.10.2017 / 12:24

4 respostas

3

Depois de muito brincar com heredocs e herestrings , parece que a solução mais simples seria esta:

ssh server.com "mkdir '/foo/bar/$final'"

Sim, bash fará a substituição de variável de $final apesar das aspas simples, assim como seria em echo "test'$final'" .

Observação: conforme apontado por @muru, isso não funcionará se $final contiver uma única citação.

    
por 16.10.2017 / 12:31
1

Citações opostas, ( isto é, aspas simples entre aspas duplas, e vice-versa ), podem substituir escapes. Sem usar escapes ou aqui documentos , considere como usar echo para exibir este texto:

He didn't look back, and said "It can't be helped."

Cercar com aspas duplas ou simples não funcionará. Citações opostas alternativas funcionam:

echo "He didn't look back, and said "'"It can'"'t be helped."'"'

Saída:

He didn't look back, and said "It can't be helped."

Infelizmente, o echo acima é tão difícil de ler quanto escapes seria.

O meio feliz é usar citações opostas e escapar conforme necessário para reduzir a monotonia visual:

echo "He didn't look back, and said \"It can't be helped.\""

Aplicado ao código:

ssh server.com 'mkdir "'"/foo/bar/$final"\"

Isso deve funcionar mesmo se $final contiver ' .

Desenrolando a cotação, temos:

  1. 'mkdir "' , que preserva um espaço e uma aspa dupla de abertura.
  2. "/foo/bar/$final" que retorna o conteúdo de $final antes de lançar ssh .
  3. \" fechando aspas duplas, preservando o nome da pasta para ssh
por 19.10.2017 / 05:51
0

Eu acho que a necessidade real depende muito de onde / quando você deseja que as variáveis sejam expandidas - antes de enviar os comandos, localmente ou depois do envio, remotamente. Ambos os casos são válidos. De qualquer maneira, se seu comando couber em uma linha, sugiro que você use o comando <<< redirection surrounding com aspas duplas ou simples, respectivamente

1. Resolvendo variáveis antes de enviar o comando

final="defined_locally"; ssh server.com <<<"final="defined_remotely" ;mkdir /foo/bar/"$final" "

2. Resolvendo variáveis após o envio do comando

final="defined_locally"; ssh server.com <<<'final="defined_remotely"; mkdir /foo/bar/"$final" '

Primeiro, criaremos

/foo/bar/defined_locally

e o segundo criará

/foo/bar/defined_remotely

diretório no servidor remoto

Como você vê, não há necessidade de escapar em ambos os casos até que você queira misturar vars locais e remotos definidos em um comando.

UPD:

<<<

estritamente falando, não é um redirecionamento, mas HERE-STRING

UPD2:

Obrigado ao @Rastapopoulos por apontar para o

Pseudo-terminal will not be allocated because stdin is not a terminal mensagens que acompanham a execução do comando

Embora não cause danos

    
por 16.10.2017 / 13:28
0

Este é um trabalho para o printf incorporado?

ldo@theon:~> f='He didn'\''t look back, and said "It can'\''t be helped."'
ldo@theon:~> echo "$f"
He didn't look back, and said "It can't be helped."
ldo@theon:~> ssh hypatia echo "$f"
bash: -c: line 0: unexpected EOF while looking for matching '"'
bash: -c: line 1: syntax error: unexpected end of file
ldo@theon:~> ssh hypatia echo $(printf %q "$f")
He didn't look back, and said "It can't be helped."
    
por 05.11.2017 / 09:10