Pasar una variable a un script bash que usa 'EOF' y considera la variable un literal [cerrado]

9

en este script termino con "$ 1" guardado en el archivo / test.

#!/bin/bash
cat > /test << 'EOF'
$1
EOF

la verdad es que necesito mantener

'EOF'

como 'EOF' porque mi argumento ($ 1) contiene signos de dólar.

pero necesito que se guarde ese argumento en lugar de $ 1

usuario72685
fuente
1
'porque mi argumento ( $1) contiene signos de dólar'. No si se refiere al primer parámetro de línea de comando. La sustitución se realizó antes de que se ejecutara el script. Tienes que escapar de él en la línea de comando.
Ricitos
Has hecho varias preguntas relacionadas sobre esta tarea que estás haciendo, y la progresión de las preguntas muestra que realmente no entiendes lo que está sucediendo y probablemente no estás eligiendo el enfoque más fácil. Es difícil ayudarlo sin saber lo que está tratando de hacer, por lo que le recomiendo que haga una pregunta donde explique claramente su tarea general y no restrinja las respuestas para usar una herramienta en particular. Por ejemplo, no diga "Quiero usar caty mantener signos de dólar", sino "Quiero modificar el httpd.confpara cambiar <alguna configuración> de <esta manera>".
Gilles 'SO- deja de ser malvado'
@Gilles, finalmente decidí escribir en un archivo diferente a través de Python y luego usar un script bash para escribir ese archivo en el archivo original que fue editado. Este proceso es mucho más fácil. cat / temp_file> $ 1
user72685
@Gilles, la razón por la cual mis preguntas no tienen sentido es porque la forma en que los scripts de bash manejan las variables que se les pasan. hay demasiadas cosas que deben escaparse y, sin embargo, no hay una función para codificar y decodificar sobre la marcha.
user72685
@Gilles, lo único que tenía sentido para mí era base64, pero ¿por qué uno tiene que codificar sus cosas para pasar a un script bash ... escapar de las cosas y luego tratar de reconstruir las cosas dentro del script bash ... los tres cortes hacia adelante para escapar de un retroceso y etc. me parece un infierno de código
user72685

Respuestas:

15

Siguiendo con su pregunta anterior , parece que quiere tanto texto no interpretado como texto interpretado en un archivo. En ese caso, use dos cats (o echos) diferentes:

cat > /test <<'EOF'
some uninterpreted text $(pwd)
not substituted: $1
EOF
cat >> /test <<EOF
but this will substitute: $1
EOF

Aquí hay un par de cosas: en primer lugar, la sintaxis heredoc con <<. Si incluye comillas en esa cadena de terminación, como en la primera de arriba, el heredoc completo no se interpreta, sin parámetros ni sustituciones. Si no usa comillas, como en el segundo cat anterior, las variables como $1serán reemplazadas por sus valores y las sustituciones de comandos se incluirán en el texto. Usted elige entre citar la cadena "EOF" o no en función de si desea sustituciones o no.

Para poner ambos correos catelectrónicos en el mismo archivo, estamos usando la >> redirección para la segunda (y más adelante) redirecciones: eso significa agregar al archivo. Para el primero, usamos un sencillo >para borrar el archivo y comenzar de nuevo.

Tenga en cuenta que, incluso cuando las variables se sustituyen , cualquier signo de dólar adicional en el valor de esa variable no se sustituye nuevamente:

foo='$bar'
bar=hello
cat <<EOF
$foo
EOF

dará salida:

$bar

sin sustituir en $barel valor de.

Sin embargo, si proporciona un "$" en el argumento de todo este script, debe escapar de él en la línea de comando o encerrarlo todo entre comillas simples. Alternativamente, la sustitución de comandos como en su otra pregunta le permite colocar el contenido de un archivo completo directamente, incluidos los signos de dólar en el contenido del archivo. Asegúrese de citar la cadena de sustitución allí:

oo.sh "$(cat myfile)"

obtendrá el cuerpo de myfileas $1y can cato entonces echosegún sea necesario. Se aplican las mismas limitaciones que en mi respuesta : hay un límite para la duración de los argumentos de la línea de comandos, y si su archivo puede ser más largo que eso, debe encontrar otro enfoque. Puede averiguar cuál es el límite en su sistema congetconf ARG_MAX

Michael Homer
fuente
1

Suena como si simplemente quisiera generar una variable en el archivo. En ese caso, esto funcionará:

echo $1 >/test

Tenga /testen cuenta que está en el directorio raíz, para el que los usuarios comunes no suelen tener permiso de escritura.

EDITAR: tenga en cuenta que necesita citar la cadena que contiene el signo de dólar en la línea de comando . Ahí es donde ocurre la sustitución, y el guión no puede hacer nada al respecto después del hecho.

Tom Zych
fuente
Creo que tienes la respuesta correcta ahora. +1
Ricitos
La respuesta de @ MichaelHomer es mucho más completa e incluye información útil sobre los documentos que había olvidado. Su respuesta debe ser aceptada (a menos que alguien más publique una aún mejor, por supuesto).
Tom Zych