使用heredoc的Shell扩展

3
如何在heredoc中对所有命令进行子shell扩展?
例如:
file=report_$(date +%Y%m%d)
cat <<EOF > $file
    date
    hostname
    echo 'End of Report'
EOF

使所有命令被评估的方式是什么?

我知道。

file=report_$(date +%Y%m%d)
cat <<EOF > $file
    $(date))
    $(hostname)
    $(echo 'End of Report')
EOF

会起作用,但是否有一种默认指定子shell的方法?

3个回答

8
您可以使用sh(或bash)作为命令,而不是cat;这将实际上将其作为shell脚本运行:
sh <<EOF > $file
    date
    hostname
    echo 'End of Report'
EOF

1
如果您想将所有行扩展为命令,则heredoc是无用的:
file="report_$(date +%Y%m%d)"
{
  date
  hostname
  echo 'End of Report'
} >| "$file"

您也可以像这样重定向 1>

file="report_$(date +%Y%m%d)"
exec 1> "$file"
date
hostname
echo 'End of Report'

0

不是那样,而是这样:

cat << EOF | sh > $file
    date
    hostname
    echo 'End of Report'
EOF

会实现相同的结果。(请注意,这是一个新的sh命令——如果需要,请使用bash而不是当前shell的子shell,因此它没有设置相同的变量。)

(编辑:我未能注意到这也是一个UUOC:无用的cat使用;请参见Explosion Pills的答案。 :-) )


这对我似乎不起作用;它似乎认为这个heredoc没有关闭。 - Explosion Pills
有两个相当不错的答案,但是“爆炸药丸”似乎略微更加直接。 - Lighthart
@torek 我刚刚复制了你的代码;可能是不同的 shell 版本。 - Explosion Pills
@Lighthart 人们似乎总是忘记从 shell 中读取 stdin 和从 pipe 中读取 stdin 之间没有区别;我经常看到像 cat file | cut 这样的东西,而 cut file 可以做同样的事情。 - Explosion Pills
@ExplosionPills:看起来剪切和粘贴在某种程度上引入了一些额外的空白(在 "EOF" 位之前)。我想责怪猫踩键盘,但当我打那个的时候她不在这里... :-) - torek
@torek 哦,显然就是这样。我应该自己看到的>< - Explosion Pills

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接