J'essaye d'interpoler des variables à l'intérieur d'un heredoc bash:
var=$1
sudo tee "/path/to/outfile" > /dev/null << "EOF"
Some text that contains my $var
EOF
Cela ne fonctionne pas comme je m'y attendais ( $var
est traité littéralement, pas développé).
J'ai besoin d'utiliser sudo tee
car la création du fichier nécessite sudo. Faire quelque chose comme:
sudo cat > /path/to/outfile <<EOT
my text...
EOT
Ne fonctionne pas, car >outfile
ouvre le fichier dans le shell actuel, qui n'utilise pas sudo.
''
), mais ne pas la citation du délimiteur active l'expansion (comme si elle était dans""
). Cependant, votre intuition est correcte en Perl, où un heredoc avec un identifiant entre guillemets se comporte comme s'il était entre guillemets simples, un avec un identifiant entre guillemets doubles comme s'il était entre guillemets et un avec un identifiant rétrogradé comme s'il était entre guillemets ! Voir: perlop: << EOFRéponses:
En réponse à votre première question, il n'y a pas de substitution de paramètre car vous avez mis le délimiteur entre guillemets - le manuel bash dit :
Si vous modifiez votre premier exemple pour utiliser à la
<<EOF
place de,<< "EOF"
vous constaterez que cela fonctionne.Dans votre deuxième exemple, le shell appelle
sudo
uniquement avec le paramètrecat
et la redirection s'applique à la sortie de ensudo cat
tant qu'utilisateur d'origine. Cela fonctionnera si vous essayez:sudo sh -c "cat > /path/to/outfile" <<EOT my text... EOT
la source
(cat > /path/to/outfile) <<EOF
à la place dusudo sh -c ... <<EOF
N'utilisez pas de guillemets avec
<<EOF
:var=$1 sudo tee "/path/to/outfile" > /dev/null <<EOF Some text that contains my $var EOF
L'expansion variable est le comportement par défaut dans here-docs. Vous désactivez ce comportement en citant l'étiquette (avec des guillemets simples ou doubles).
la source
En corollaire tardif des réponses précédentes ici, vous vous retrouvez probablement dans des situations où vous voulez que certaines variables, mais pas toutes , soient interpolées. Vous pouvez résoudre ce problème en utilisant des contre-obliques pour échapper aux signes dollar et aux contre-obliques; ou vous pouvez mettre le texte statique dans une variable.
Name='Rich Ba$tard' dough='$$$dollars$$$' cat <<____HERE $Name, you can win a lot of $dough this week! Notice that \`backticks' need escaping if you want literal text, not `pwd`, just like in variables like \$HOME (current value: $HOME) ____HERE
Démo: https://ideone.com/rMF2XA
Notez que n'importe lequel des mécanismes de citation -
\____HERE
ou"____HERE"
ou'____HERE'
- désactivera toute interpolation variable, et transformera le document ici en un morceau de texte littéral.Une tâche courante consiste à combiner des variables locales avec un script qui doit être évalué par un shell, un langage de programmation ou un hôte distant différent.
local=$(uname) ssh -t remote <<: echo "$local is the value from the host which ran the ssh command" # Prevent here doc from expanding locally; remote won't see backslash remote=\$(uname) # Same here echo "\$remote is the value from the host we ssh:ed to" :
la source