Cómo imprimir "$" en el documento aquí

42

¿Cómo puedo repetir "$" en un documento aquí en bash?

Por ejemplo, quiero tener un archivo con el contenido en un servidor remoto como $ABC=home_dir.

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

Pero se trataría como una variable. ¿Cómo puedo imprimir un literal $?

usuario21485
fuente
2
puedes usar comillas simples
Rahul Patil
2
Eso es mucha indirección. ¿Está seguro de que no puede crear el archivo en el host local y luego scp?
l0b0

Respuestas:

65

Si desea escribir un documento aquí y no desea que CUALQUIERA del documento se expanda o se interprete cualquier carácter especial, puede citar la etiqueta con comillas simples, como esta:

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

Sin embargo, su situación como se describe en su ejemplo es mucho más compleja, porque realmente está enviando este contenido a través de ssh, a un sistema remoto, para que sea ejecutado por sudo, que también invoca un shell (y ese shell expandirá el contenido también). Necesitará más niveles de citas para hacerlo bien, pero incluso con eso no funcionará porque sudo requiere un terminal (por lo que puede solicitar una contraseña) y ha redirigido desde stdin. Incluso el uso ssh -tno ayudará aquí.

También estoy de acuerdo con Johan. No está claro que esto sea realmente lo que quieres; tenga en cuenta que no es legal asignar un valor a una referencia de variable de shell, por lo que si se supone que este archivo que está intentando crear es un script de shell, no funcionará como lo ha descrito. Tal vez si retrocede un poco y describe lo que realmente quiere hacer, podemos ayudarlo más.

Científico loco
fuente
Esta es la mejor respuesta porque puede atender documentos AQUÍ muy largos. Es (principalmente) a prueba de idiotas.
Felipe Alvarez
22

Escapar del $

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

No sé cuál es su caso de uso, pero generalmente desea en home_dir=$ABClugar de $ABC=home_dir.

lesmana
fuente
2
Esta solución funcionará, pero ¿es eso realmente lo que quiere el OP? Parece generar un script de shell que, cuando se ejecuta, almacenará en "archivo" una cadena que desreferenciará ABC para el lado izquierdo de la tarea y probablemente terminará almacenando =home_diren el archivo. Por supuesto, no sé cuál es el caso de uso ...
Johan
2
Esto hará $que se envíe un literal al shell remoto, pero luego ese shell se expandirá $ABCantes de hacer eco de la cadena file. Para escribir el literal $en el archivo, necesitará otra barra diagonal inversa (con escape): echo "\\\$ABC=home_dir"para que el shell remoto reciba echo "\$ABC=home_dir".
chepner
9

La forma más barata de escapar sería

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

Se ahorra un nivel de cita enviando la cadena a un catproceso en el extremo remoto:

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

Las comillas simples protegen el $en el extremo local, y la cadena nunca es vista por el shell en el otro porque es leída directamente por cat(via sudo), en lugar de ser un argumento para otro comando de shell.

Con su código, necesitaría una capa adicional de escape para proteger $:

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

Debe enviar un literal \$al host remoto, de modo que el shell remoto escriba un literal $en el archivo. También podría simplificar esto citando el marcador here-doc:

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