在 bash heredoc 中使用变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4937792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using variables inside a bash heredoc
提问by Jon
I'm trying to interpolate variables inside of a bash heredoc:
我正在尝试在 bash heredoc 中插入变量:
var=
sudo tee "/path/to/outfile" > /dev/null << "EOF"
Some text that contains my $var
EOF
This isn't working as I'd expect ($var
is treated literally, not expanded).
这不像我期望的那样工作(按$var
字面处理,而不是扩展)。
I need to use sudo tee
because creating the file requires sudo. Doing something like:
我需要使用,sudo tee
因为创建文件需要 sudo。做类似的事情:
sudo cat > /path/to/outfile <<EOT
my text...
EOT
Doesn't work, because >outfile
opens the file in the current shell, which is not using sudo.
不起作用,因为>outfile
在当前 shell 中打开文件,它没有使用 sudo。
回答by Mark Longair
In answer to your first question, there's no parameter substitution because you've put the delimiter in quotes - the bash manual says:
在回答您的第一个问题时,没有参数替换,因为您已将分隔符放在引号中 - bash 手册说:
The format of here-documents is:
<<[-]word here-document delimiter
No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any characters in wordare quoted, the delimiteris the result of quote removal on word, and the lines in the here-document are not expanded. If wordis unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. [...]
here-document 的格式为:
<<[-]word here-document delimiter
不会对word执行参数扩展、命令替换、算术扩展或路径名扩展。如果word中的任何字符被引用,则 分隔符是word上引用去除的结果,并且here-document中的行没有被扩展。如果word 没有被引用,here-document 的所有行都会进行参数扩展、命令替换和算术扩展。[...]
If you change your first example to use <<EOF
instead of << "EOF"
you'll find that it works.
如果您将第一个示例更改为使用<<EOF
而不是使用,<< "EOF"
您会发现它有效。
In your second example, the shell invokes sudo
only with the parameter cat
, and the redirection applies to the output of sudo cat
as the original user. It'll work if you try:
在您的第二个示例中,shellsudo
仅使用参数调用cat
,并且重定向适用于sudo cat
作为原始用户的输出。如果您尝试,它会起作用:
sudo sh -c "cat > /path/to/outfile" <<EOT
my text...
EOT
回答by mob
Don't use quotes with <<EOF
:
不要使用引号<<EOF
:
var=
sudo tee "/path/to/outfile" > /dev/null <<EOF
Some text that contains my $var
EOF
Variable expansion is the default behavior inside of here-docs. You disable that behavior by quoting the label (with single or double quotes).
变量扩展是 here-docs 中的默认行为。您可以通过引用标签(使用单引号或双引号)来禁用该行为。
回答by tripleee
As a late corolloary to the earlier answers here, you probably end up in situations where you want somebut not allvariables to be interpolated. You can solve that by using backslashes to escape dollar signs and backticks; or you can put the static text in a 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
Demo: https://ideone.com/rMF2XA
Note that any of the quoting mechanisms -- \____HERE
or "____HERE"
or '____HERE'
-- will disable all variable interpolation, and turn the here-document into a piece of literal text.
请注意,任何引用机制——\____HERE
或"____HERE"
或'____HERE'
——将禁用所有变量插值,并将此处文档转换为一段文字文本。
A common task is to combine local variables with script which should be evaluated by a different shell, programming language, or remote host.
一个常见的任务是将局部变量与脚本结合起来,脚本应该由不同的 shell、编程语言或远程主机评估。
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"
: