web-dev-qa-db-fra.com

Comment éviter les variables d'extension heredoc?

J'essaie de créer un fichier de script en utilisant une chaîne de substitution d'ENV mais je veux aussi empêcher certains de s'échapper

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
"

Il en résulte que ce n'est pas bon car les myvariable_final ne sont pas échappés et substitués comme celui des dépendances du script init ($ 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 j'essaye de mettre une barre oblique inversée \ derrière les dollars $, J'arrive à éviter la substitution mais j'obtiens une barre oblique inverse \:

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
"

résulte 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}"

Résultat recherché/attendu qui aurait dû être:

#!/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}"

résolu en mettant des guillemets autour de EOF comme ci-dessous et en utilisant une barre oblique inverse pour contrôler l'échappement en cas de besoin

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
"
56
TheCodeKiller

Utilisez simplement 'EOF' pour empêcher l'expansion de la variable:

Sudo /bin/su -c "cat << 'EOF' > /etc/init.d/my-script
#                       ^   ^

De man bash:

ici les documents

Ce type de redirection demande au Shell de lire les entrées de la source actuelle jusqu'à ce qu'une ligne contenant uniquement un délimiteur (sans espaces de fin) soit vue. Toutes les lignes lues jusqu'à ce point sont ensuite utilisées comme entrée standard pour une commande.

Le format des documents ici est:

      <<[-]Word
              here-document
      delimiter

Aucune expansion de paramètre, substitution de commande, expansion arithmétique ou expansion de nom de chemin n'est effectuée sur Word. Si des caractères dans Word sont cités, le délimiteur est le résultat de la suppression des guillemets sur Word et les lignes du document ici ne sont pas développées. Si Word n'est pas cité, toutes les lignes du document ici sont soumises à l'expansion des paramètres, à la substitution de commandes et à l'expansion arithmétique. Dans ce dernier cas, la séquence de caractères\est ignorée et\doit être utilisée pour citer les caractères \, $ et `.

137
fedorqui

lorsque vous utilisez la commande su, mettez la commande elle-même entre guillemets sigle et échappez simplement $ avec une barre oblique inverse. les variables d'espace réservé doivent être définies dans le contexte de la commande bash (ici après su). vous devez donc faire quelque chose comme

su -c 'ph="ph"; cat << EOF > script 
varinscript=$ph
var=\${var}
EOF'
2
Marc Bredt