在bash heredoc中使用变量

Jon*_*Jon 175 variables bash heredoc sh

我正在尝试在bash heredoc中插入变量:

var=$1
sudo tee "/path/to/outfile" > /dev/null << "EOF"
Some text that contains my $var
EOF
Run Code Online (Sandbox Code Playgroud)

这不符合我的预期(按$var字面意思处理,不进行扩展).

我需要使用,sudo tee因为创建文件需要sudo.做类似的事情:

sudo cat > /path/to/outfile <<EOT
my text...
EOT
Run Code Online (Sandbox Code Playgroud)

不起作用,因为>outfile在当前shell中打开文件,而不使用sudo.

Mar*_*air 231

在回答你的第一个问题时,没有参数替换,因为你已将分隔符放在引号中 - bash手册说:

here-documents的格式是:

      <<[-]word
              here-document
      delimiter
Run Code Online (Sandbox Code Playgroud)

不对执行参数扩展,命令替换,算术扩展或路径名扩展.如果引用单词中的任何字符,则 分隔符是单词上的引号删除的结果,并且不会展开here-document中的行.如果word不加引号,则here-document的所有行都要进行参数扩展,命令替换和算术扩展.[...]

如果你改变你的第一个例子<<EOF而不是<< "EOF"你会发现它的工作原理.

在第二个示例中,shell sudo仅使用参数调用cat,重定向适用于sudo cat原始用户的输出.如果你尝试它会工作:

sudo sh -c "cat > /path/to/outfile" <<EOT
my text...
EOT
Run Code Online (Sandbox Code Playgroud)

  • 扩展适用于HEREDOC中的单引号变量。 (2认同)
  • 如果您感兴趣,您也可以这样做:`(cat &gt; /path/to/outfile) &lt;&lt;EOF` 代替 `sudo sh -c ... &lt;&lt;EOF` (2认同)

mob*_*mob 90

不要使用以下引号<<EOF:

var=$1
sudo tee "/path/to/outfile" > /dev/null <<EOF
Some text that contains my $var
EOF
Run Code Online (Sandbox Code Playgroud)

变量扩展是here-docs中的默认行为.您可以通过引用标签(使用单引号或双引号)来禁用该行为.


tri*_*eee 21

作为此处早期答案的较晚推论,您可能最终会希望插补一些但不是全部变量。您可以通过使用反斜杠来避免美元符号和反引号来解决此问题;或者您可以将静态文本放在变量中。

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
Run Code Online (Sandbox Code Playgroud)

演示:https//ideone.com/rMF2XA

请注意,任何一种引用机制(\____HERE"____HERE"'____HERE')都将禁用所有变量插值,并将此处文档转换为一段文字文本。

一个常见的任务是将局部变量与脚本结合在一起,而脚本应由其他外壳程序,编程语言或远程主机进行评估。

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"
:
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么这被否决了,但它添加了一个有效的注释,该注释_未_包含在现在更高投票的答案中。 (3认同)