Jak uniknąć zmiennych rozszerzających heredoc? [duplikat]

To pytanie ma już odpowiedź tutaj:

Próbuję utworzyć plik skryptu używając zastępczego łańcucha z ENV, ale chcę również zapobiec ucieczce

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
"

Wynika, że nie jest dobre, ponieważ myvariable_final nie są uciekane i zastępowane jako jeden ze skryptów init zależności ($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=,"

Jeśli próbuję umieścić ukośnik \ za dolarami $, udaje mi się uniknąć substytucji, ale dostaję niechciany ukośnik \:

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
"

Wyniki w:

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

Wanted/attended result whould have been:

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

Rozwiązano poprzez umieszczenie cudzysłowu wokół EOF Jak poniżej i użycie odwrotnego ukośnika do kontrolowania ucieczki w razie potrzeby

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
"
Author: TheCodeKiller, 2015-01-13

2 answers

Wystarczy użyć 'EOF', aby zapobiec rozszerzeniu zmiennej:

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

From man bash:

Tutaj Dokumenty

Ten typ przekierowania nakazuje powłoce odczytywanie danych wejściowych z bieżącego źródła aż do linii zawierającej tylko ogranicznik (bez widoczne są puste pola). Wszystkie linie odczytane do tego momentu są następnie używany jako standardowe wejście dla polecenia.

Format Dokumentów tutaj to:

      <<[-]word
              here-document
      delimiter

Brak parametru ekspansja, zastępowanie poleceń, ekspansja arytmetyczna, lub rozszerzenie ścieżki jest wykonywane w programie word. Jeśli jakieś znaki w słowie są cytowane, ogranicznik jest wynikiem usuwania cudzysłowu na Wordzie, a linie w dokumencie here nie są rozszerzane. jeśli word jest nienotowane, wszystkie wiersze dokumentu tutaj są poddawane parametrowi Rozszerzanie, zastępowanie poleceń i rozszerzanie arytmetyczne . W w drugim przypadku, sekwencja znaków \ jest ignorowana, a \ należy stosować do Zacytuj znaki \, $ i'.

 98
Author: fedorqui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-11 09:55:32

Podczas używania polecenia su umieść samo polecenie w cudzysłowach sigle i po prostu unikaj $ z odwrotnym ukośnikiem. zmienne zastępcze należy ustawić w Komendzie Bash context (tutaj po su). więc musisz zrobić sth jak

su -c 'ph="ph"; cat << EOF > script 
varinscript=$ph
var=\${var}
EOF'
 1
Author: Marc Bredt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-06 11:16:23