我如何在这里写一个文档到Bash脚本文件?


当前回答

对于将来可能遇到这个问题的人,下面的格式是有效的:

(cat <<- _EOF_
        LogFile /var/log/clamd.log
        LogTime yes
        DatabaseDirectory /var/lib/clamav
        LocalSocket /tmp/clamd.socket
        TCPAddr 127.0.0.1
        SelfCheck 1020
        ScanPDF yes
        _EOF_
) > /etc/clamd.conf

其他回答

根据@Livven的回答,这里有一些有用的组合。

variable substitution, leading tab retained, overwrite file, echo to stdout tee /path/to/file <<EOF ${variable} EOF no variable substitution, leading tab retained, overwrite file, echo to stdout tee /path/to/file <<'EOF' ${variable} EOF variable substitution, leading tab removed, overwrite file, echo to stdout tee /path/to/file <<-EOF ${variable} EOF variable substitution, leading tab retained, append to file, echo to stdout tee -a /path/to/file <<EOF ${variable} EOF variable substitution, leading tab retained, overwrite file, no echo to stdout tee /path/to/file <<EOF >/dev/null ${variable} EOF the above can be combined with sudo as well sudo -u USER tee /path/to/file <<EOF ${variable} EOF

阅读高级bash脚本编写指南第19章。这里的文档。

下面是一个将内容写入/tmp/yourfilehere文件的示例

cat << EOF > /tmp/yourfilehere
These contents will be written to the file.
        This line is indented.
EOF

注意,最后的'EOF'(限制字符串)在单词前面不应该有任何空白,因为这意味着限制字符串将不会被识别。

在shell脚本中,您可能希望使用缩进来使代码可读,但这可能会产生对here文档中的文本缩进的不良影响。在这种情况下,使用<<-(后面跟着破折号)禁用开头的制表符(注意,为了测试这一点,您需要用制表符替换开头的空白,因为我不能在这里打印实际的制表符)。

#!/usr/bin/env bash

if true ; then
    cat <<- EOF > /tmp/yourfilehere
    The leading tab is ignored.
    EOF
fi

如果你不想解释文本中的变量,那么使用单引号:

cat << 'EOF' > /tmp/yourfilehere
The variable $FOO will not be interpreted.
EOF

通过命令管道来管道heredoc:

cat <<'EOF' |  sed 's/a/b/'
foo
bar
baz
EOF

输出:

foo
bbr
bbz

... 或者使用sudo将heredoc写入文件:

cat <<'EOF' |  sed 's/a/b/' | sudo tee /etc/config_file.conf
foo
bar
baz
EOF

使用tee代替cat和I/O重定向可能会有用:

tee newfile <<EOF
line 1
line 2
line 3
EOF

它更简洁,而且与重定向操作符不同,如果您需要以根权限写入文件,它可以与sudo结合使用。

注意:

以下是本主题中其他答案的浓缩和组织,尤其是Stefan Lasiewski和Serge Stroobandt的优秀作品 Lasiewski和我推荐高级bash脚本编写指南中的Ch 19 (Here Documents)

问题(如何在bash脚本中将here文档(又名heredoc)写入文件?)有(至少)3个主要的独立维度或子问题:

要覆盖现有文件、追加到现有文件还是写入新文件? 您的用户或其他用户(例如root)拥有该文件吗? 您是想按字面意思写heredoc的内容,还是让bash在heredoc内解释变量引用?

(还有其他我认为不重要的方面/子问题。考虑编辑这个答案来添加它们!)下面是上面列出的问题的一些更重要的维度组合,使用各种不同的分隔标识符——关于EOF没有什么神圣的,只要确保你用作分隔标识符的字符串没有出现在你的heredoc中:

To overwrite an existing file (or write to a new file) that you own, substituting variable references inside the heredoc: cat << EOF > /path/to/your/file This line will write to the file. ${THIS} will also write to the file, with the variable contents substituted. EOF To append an existing file (or write to a new file) that you own, substituting variable references inside the heredoc: cat << FOE >> /path/to/your/file This line will write to the file. ${THIS} will also write to the file, with the variable contents substituted. FOE To overwrite an existing file (or write to a new file) that you own, with the literal contents of the heredoc: cat << 'END_OF_FILE' > /path/to/your/file This line will write to the file. ${THIS} will also write to the file, without the variable contents substituted. END_OF_FILE To append an existing file (or write to a new file) that you own, with the literal contents of the heredoc: cat << 'eof' >> /path/to/your/file This line will write to the file. ${THIS} will also write to the file, without the variable contents substituted. eof To overwrite an existing file (or write to a new file) owned by root, substituting variable references inside the heredoc: cat << until_it_ends | sudo tee /path/to/your/file This line will write to the file. ${THIS} will also write to the file, with the variable contents substituted. until_it_ends To append an existing file (or write to a new file) owned by user=foo, with the literal contents of the heredoc: cat << 'Screw_you_Foo' | sudo -u foo tee -a /path/to/your/file This line will write to the file. ${THIS} will also write to the file, without the variable contents substituted. Screw_you_Foo

对于将来可能遇到这个问题的人,下面的格式是有效的:

(cat <<- _EOF_
        LogFile /var/log/clamd.log
        LogTime yes
        DatabaseDirectory /var/lib/clamav
        LocalSocket /tmp/clamd.socket
        TCPAddr 127.0.0.1
        SelfCheck 1020
        ScanPDF yes
        _EOF_
) > /etc/clamd.conf