Como imprimir "$" no documento aqui

42

Como posso ecoar "$" em um documento aqui no bash?

Por exemplo, eu quero ter um arquivo com o conteúdo no servidor remoto como $ABC=home_dir.

$ ssh hostname sudo -s <<EOF
echo "$ABC=home_dir" > file
EOF

Mas isso seria tratado como uma variável. Como posso imprimir um literal $?

user21485
fonte
2
você pode usar aspas simples
Rahul Patil
2
Isso é muita indireção acontecendo. Tem certeza de que não pode criar o arquivo no host local e depois scp?
L0b0 19/03/2013

Respostas:

65

Se você deseja escrever um documento aqui e não deseja que QUALQUER documento seja expandido ou que qualquer caractere especial seja interpretado, você pode citar o rótulo com aspas simples, como este:

$ cat >file <<'EOF'
echo "$ABC=home_dir"
EOF

No entanto, sua situação, conforme descrito no seu exemplo, é muito mais complexa, porque você está realmente enviando esse conteúdo através do ssh, para um sistema remoto, para ser executado pelo sudo, que também está chamando um shell (e, assim, o shell expandirá o conteúdo também). Você precisará de mais níveis de cotação para fazer isso direito, mas mesmo assim ainda não funcionará porque o sudo requer um terminal (para que possa solicitar uma senha) e você o redirecionou do stdin. Mesmo usando ssh -tnão vai ajudar aqui.

Também concordo com Johan. Não está claro que isso é realmente o que você deseja; observe que não é legal atribuir um valor a uma referência de variável do shell; portanto, se esse arquivo que você está tentando criar for um script de shell, ele não funcionará como você o descreveu. Talvez se você voltar um pouco e descrever o que realmente deseja fazer, possamos ajudar mais.

Cientista maluco
fonte
Esta é a melhor resposta, pois pode atender a documentos AQUI muito longos. É (principalmente) à prova de idiotas.
Felipe Alvarez
22

Escape the $

$ ssh hostname sudo -s <<EOF
echo "\$ABC=home_dir" > file
EOF

Não sei qual é o seu caso de uso, mas geralmente você deseja, em home_dir=$ABCvez de $ABC=home_dir.

lesmana
fonte
2
Essa solução funcionará, mas é isso mesmo que o OP deseja? Parece gerar um script de shell que, quando executado, armazena no "arquivo" uma string que desreferencia o ABC do lado esquerdo da atribuição e provavelmente acaba armazenando =home_dirno arquivo? Claro que eu não sei o que o caso de uso é ...
Johan
2
Isso fará com que um literal $seja enviado ao shell remoto, mas esse shell será expandido $ABCantes de ecoar a string para file. Para gravar o literal $no arquivo, você precisará de outra barra invertida (com escape):, echo "\\\$ABC=home_dir"para que o shell remoto receba echo "\$ABC=home_dir".
chepner
9

A maneira mais barata de escapar seria

$ ssh hostname sudo -s << \EOF
echo "$ABC=home_dir" > file
EOF
Bernhard
fonte
4

Você economiza um nível de cotação enviando a string para um catprocesso no final remoto:

echo 'echo $ABC=home_dir' | ssh hostname sudo -s "cat > file"

As aspas simples protegem a $extremidade local e a string nunca é vista pelo shell do outro porque é lida diretamente por cat(via sudo), em vez de ser um argumento para outro comando do shell.

Com seu código, você precisaria de uma camada extra de escape para proteger $:

$ ssh hostname sudo -s <<EOF
echo "\\\$ABC=home_dir" > file
EOF

Você precisa enviar um literal \$para o host remoto, para que o shell remoto grave um literal $no arquivo. Você também pode simplificar isso citando o marcador aqui-doc:

$ ssh hostname sudo -s <<\EOF
echo "\$ABC=home_dir" > file
EOF
chepner
fonte