Come stampare "$" nel documento qui


42

Come posso echo "$" in un here-doc in bash?

Ad esempio, voglio avere un file con il contenuto sul server remoto come $ABC=home_dir.

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

Ma sarebbe trattato come una variabile. Come posso stampare un letterale $?


2
puoi usare virgolette singole
Rahul Patil,

2
Questo è un sacco di indiretta in corso. Sei sicuro di non poter creare il file sull'host locale e poi scp?
l0b0

Risposte:


65

Se vuoi scrivere un documento qui e non vuoi che NESSUNA del documento venga espanso o interpretato alcun carattere speciale, puoi citare l'etichetta con virgolette singole, come questa:

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

Tuttavia, la tua situazione come descritta nel tuo esempio è molto più complessa, perché stai davvero inviando questo contenuto tramite ssh, a un sistema remoto, per essere eseguito da sudo che sta anche invocando una shell (e in tal modo la shell espanderà il contenuto anche). Avrai bisogno di più livelli di quotazione per farlo bene, ma anche con quello non funzionerà ancora perché sudo richiede un terminale (quindi può chiedere una password) e sei reindirizzato da stdin. Anche l'utilizzo ssh -tnon aiuta qui.

Anche io sono d'accordo con Johan. Non è chiaro che questo è davvero quello che vuoi; nota che non è legale assegnare un valore a un riferimento alla variabile shell, quindi se questo file che stai cercando di creare dovrebbe essere uno script shell, non funzionerà come l'hai descritto. Forse, se fai un backup e descrivi ciò che vuoi veramente fare, possiamo aiutarti di più.


Questa è la risposta migliore perché può soddisfare documenti HERE molto lunghi. È (principalmente) a prova di idiota.
Felipe Alvarez,

22

Sfuggire al $

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

Non so quale sia il tuo caso d'uso, ma di solito vuoi home_dir=$ABCinvece $ABC=home_dir.


2
Questa soluzione funzionerà, ma è proprio quello che vuole l'OP? Sembra generare uno script di shell che, una volta eseguito, memorizzerà in "file" una stringa che dereferirà ABC per il lato sinistro dell'assegnazione e probabilmente finirà per essere archiviata =home_dirnel file? Ovviamente non so quale sia il caso d'uso ...
Johan

2
Questo causerà un letterale $da inviare alla shell remota, ma poi quella shell si espanderà $ABCprima di fare eco alla stringa file. Per scrivere il valore letterale $nel file, è necessaria un'altra barra rovesciata (con escape): in echo "\\\$ABC=home_dir"modo che la shell remota riceva echo "\$ABC=home_dir".
chepner,

9

Il modo più economico per fuggire sarebbe

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

4

Ti risparmi un livello di offerta inviando la stringa a un catprocesso sull'estremità remota:

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

Le virgolette singole proteggono l' $estremità locale e la stringa non viene mai vista dalla shell dall'altra perché viene letta direttamente da cat(via sudo), piuttosto che essere un argomento per un altro comando shell.

Con il tuo codice, avrai bisogno di un ulteriore livello di escape per proteggere $:

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

È necessario inviare un valore letterale \$all'host remoto, in modo che la shell remota scriva un valore letterale $nel file. Puoi anche semplificarlo citando il marcatore here-doc:

$ ssh hostname sudo -s <<\EOF
echo "\$ABC=home_dir" > file
EOF
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.