Eu pego esse exemplo simples no bash:
echo a "b c" d
A saída correta é:
a b c d
O que é internamente 'codificado' como uma matriz de três argumentos, enquanto o do meio (contendo b
e c
) tem 4 caracteres e contém 2 espaços. Esta é a saída de depuração quando set -x
está habilitado no bash (não traço)
echo a "b c" d
+ echo a 'b b' c
a b b c
Agora, o comando ssh parece ignorar completamente isso e parece concatenar isso internamente a uma única string que não está correta; do contrário, não posso explicar os resultados:
$ ssh user@remotehost -- echo a "b b" c
+ ssh user@remotehost -- echo a 'b b' c
a b b c
$ ssh user@remotehost echo a "b b" c
+ ssh user@remotehost echo a 'b b' c
a b b c
$ ssh user@remotehost 'echo a "b b" c'
+ ssh user@remotehost 'echo a "b b" c'
a b b c
Como você pode ver, a última linha funciona melhor, mas eu tenho um problema se a string ficar mais complicada, por exemplo:
$ text="doesn't work"
+ text='doesn'\''t work'
$ echo "$text"
+ echo 'doesn'\''t work'
doesn't work
$ ssh user@remotehost echo "$text"
+ ssh user@remotehost echo 'doesn'\''t work'
bash: -c: line 0: unexpected EOF while looking for matching '''
bash: -c: line 1: syntax error: unexpected end of file
$ ssh user@remotehost "echo $text"
+ ssh user@remotehost 'echo doesn'\''t work'
bash: -c: line 0: unexpected EOF while looking for matching '''
bash: -c: line 1: syntax error: unexpected end of file
$ ssh user@remotehost "echo \'$text\'"
+ ssh user@remotehost 'echo \'\''doesn'\''t work\'\'''
'doesnt work\
$ ssh user@remotehost "echo '$text'"
+ ssh user@remotehost 'echo '\''doesn'\''t work'\'''
bash: -c: line 0: unexpected EOF while looking for matching '''
bash: -c: line 1: syntax error: unexpected end of file
A questão é: Eu existe qualquer maneira de executar um comando remoto e passar variáveis da melhor maneira prática ( "$variable"
, vários argumentos), para que eu não tenha se importar com seu conteúdo ou se seu conteúdo é perigoso?
A mesma limitação também parece se aplicar a sh -c
, que é provavelmente a fonte do problema, outros comandos fazem melhor (eles chamam o binário diretamente em vez de usar um shell):
$ sudo -- echo a 'b b' c
[sudo] password for user:
a b b c
$ nohup echo a 'b b' c
nohup: ignoring input and appending output to 'nohup.out'
$ cat nohup.out
a b b c
Tags ssh escape-characters