bash - ¿Cómo evitar las variables de expansión heredoc?
escaping substitution (2)
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo cat << EOF >> un archivo que contiene código? 3 respuestas
Estoy tratando de crear un archivo de script usando una cadena de sustitución de ENV pero también quiero evitar que algunos escapen
export PLACEHOLDER1="myPlaceholder1Value"
export PLACEHOLDER2="myPlaceholder2Value"
sudo /bin/su -c "cat << EOF > /etc/init.d/my-script
#!/bin/bash
#
### BEGIN INIT INFO
# Provides: my-script
# Required-Start: /$remote_fs /$syslog
# Required-Stop: /$remote_fs /$syslog
# Should-Start: /$network /$time
# Should-Stop: /$network /$time
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: blabla
# Description: bla bla desc
#
### END INIT INFO
#
myvariable_1=toto$PLACEHOLDER1
myvariable_2=titi$PLACEHOLDER2
myvariable_final=/"dynamicvar=/${myvariable_1},/${myvariable_2}/"
EOF
"
Resulta en que no es bueno ya que myvariable_final no se escapa y se sustituye como el de las dependencias de script de inicio ($ remote_fs, $ syslog, $ network, $ time)
#!/bin/bash
#
### BEGIN INIT INFO
# Provides: my-script
# Required-Start:
# Required-Stop:
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: blabla
# Description: bla bla desc
#
### END INIT INFO
#
myvariable_1=totomyPlaceholder1Value
myvariable_2=titimyPlaceholder2Value
myvariable_final="dynamicvar=,"
Si trato de poner una barra invertida
/
detrás de los dólares
$
, logro evitar la sustitución pero obtengo una barra invertida no deseada
/
:
export PLACEHOLDER1="myPlaceholder1Value"
export PLACEHOLDER2="myPlaceholder2Value"
sudo /bin/su -c "cat << EOF > /etc/init.d/my-script
#!/bin/bash
#
### BEGIN INIT INFO
# Provides: my-script
# Required-Start: /$/remote_fs /$/syslog
# Required-Stop: /$remote_fs /$syslog
# Should-Start: /$network /$time
# Should-Stop: /$network /$time
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: blabla
# Description: bla bla desc
#
### END INIT INFO
#
myvariable_1=toto$PLACEHOLDER1
myvariable_2=titi$PLACEHOLDER2
myvariable_final=/"dynamicvar=/$/{myvariable_1},/$/{myvariable_2}/"
EOF
"
resultados en:
#!/bin/bash
#
### BEGIN INIT INFO
# Provides: my-script
# Required-Start: $/remote_fs $/syslog
# Required-Stop:
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: blabla
# Description: bla bla desc
#
### END INIT INFO
#
myvariable_1=totomyPlaceholder1Value
myvariable_2=titimyPlaceholder2Value
myvariable_final="dynamicvar=$/{myvariable_1},$/{myvariable_2}"
El resultado deseado / atendido debería haber sido:
#!/bin/bash
#
### BEGIN INIT INFO
# Provides: my-script
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: $network $time
# Should-Stop: $network $time
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: blabla
# Description: bla bla desc
#
### END INIT INFO
#
myvariable_1=totomyPlaceholder1Value
myvariable_2=titimyPlaceholder2Value
myvariable_final="dynamicvar=${myvariable_1},${myvariable_2}"
resuelto poniendo una cita alrededor del EOF como se muestra a continuación y usando una barra invertida para controlar el escape cuando sea necesario
export PLACEHOLDER1="myPlaceholder1Value"
export PLACEHOLDER2="myPlaceholder2Value"
sudo /bin/su -c "cat << ''EOF'' > /etc/init.d/my-script
#!/bin/bash
#
### BEGIN INIT INFO
# Provides: my-script
# Required-Start: /$remote_fs /$syslog
# Required-Stop: /$remote_fs /$syslog
# Should-Start: /$network /$time
# Should-Stop: /$network /$time
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: blabla
# Description: bla bla desc
#
### END INIT INFO
#
myvariable_1=toto$PLACEHOLDER1
myvariable_2=titi$PLACEHOLDER2
myvariable_final=/"dynamicvar=/${myvariable_1},/${myvariable_2}/"
EOF
"
Simplemente use
''EOF''
para evitar que la variable se expanda:
sudo /bin/su -c "cat << ''EOF'' > /etc/init.d/my-script
# ^ ^
De
man bash
:
Aquí documentos
Este tipo de redirección indica al shell que lea la entrada de la fuente actual hasta que se vea una línea que contenga solo delimitador (sin espacios en blanco). Todas las líneas leídas hasta ese punto se utilizan como entrada estándar para un comando.
El formato de los documentos aquí es:
<<[-]word here-document delimiter
No se realiza expansión de parámetros, sustitución de comandos, expansión aritmética o expansión de nombre de ruta en Word. Si se citan caracteres en palabras, el delimitador es el resultado de la eliminación de comillas en palabras, y las líneas en el documento aquí no se expanden. Si la palabra no está entre comillas, todas las líneas del documento aquí están sujetas a expansión de parámetros, sustitución de comandos y expansión aritmética . En el último caso, la secuencia de caracteres / se ignora y / debe usarse para citar los caracteres /, $ y `.
cuando use el comando su, coloque el comando en comillas simples y simplemente escape de $ con una barra invertida. las variables de marcador de posición deben establecerse en el contexto de comando bash (aquí después de su). entonces necesitas hacer algo como
su -c ''ph="ph"; cat << EOF > script
varinscript=$ph
var=/${var}
EOF''