bash escaping substitution heredoc

bash - ¿Cómo evitar las variables de expansión heredoc?



escaping substitution (2)

Esta pregunta ya tiene una respuesta aquí:

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''