如何在Bash脚本中将此文档写入文件?
答案 0 :(得分:908)
阅读Advanced Bash-Scripting Guide Chapter 19. Here Documents。
这是一个将内容写入/tmp/yourfilehere
cat << EOF > /tmp/yourfilehere
These contents will be written to the file.
This line is indented.
EOF
请注意,最终的'EOF'(LimitString
)不应该在单词前面有任何空格,因为这意味着LimitString
将无法被识别。
在shell脚本中,您可能希望使用缩进来使代码可读,但是这会使您在此文档中缩进文本产生不良影响。在这种情况下,使用<<-
(后跟短划线)来禁用主要标签(注意,为了测试这一点,您需要用标签字符替换前导空格,因为我无法在此处打印实际的制表符。)
#!/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
答案 1 :(得分:124)
不使用cat
和I / O重定向,而是使用tee
代替:
tee newfile <<EOF
line 1
line 2
line 3
EOF
它更简洁,加上与重定向运算符不同,如果您需要使用root权限写入文件,它可以与sudo
结合使用。
答案 2 :(得分:50)
注意:强>
问题(如何在bash脚本中将文档(又名 heredoc )写入文件?)(至少)有3个主要独立维度或子项:
root
)是否拥有该文件?(还有其他维度/子问题我认为不重要。请考虑编辑此答案以添加它们!)以下是上面列出的问题维度的一些更重要的组合,以及各种不同的分隔标识符 - - EOF
没有什么神圣之处,只要确保你用作分界标识符的字符串在你的heredoc中出现 not :
要覆盖您拥有的现有文件(或写入新文件),请替换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
要附加您拥有的现有文件(或写入新文件),请替换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
使用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
使用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
要覆盖root拥有的现有文件(或写入新文件),替换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
使用heredoc的文字内容附加user = foo拥有的现有文件(或写入新文件):
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
答案 3 :(得分:28)
在@Livven的answer上构建,这里有一些有用的组合。
变量替换,保留前导标签,覆盖文件,回显到标准输出
tee /path/to/file <<EOF
${variable}
EOF
无变量替换,保留前置标签,覆盖文件,回显到标准输出
tee /path/to/file <<'EOF'
${variable}
EOF
变量替换,删除前导标签,覆盖文件,回显到标准输出
tee /path/to/file <<-EOF
${variable}
EOF
变量替换,保留前置标签,附加到文件,回显到标准输出
tee -a /path/to/file <<EOF
${variable}
EOF
变量替换,保留前置标签,覆盖文件,没有回显到标准输出
tee /path/to/file <<EOF >/dev/null
${variable}
EOF
以上内容也可以与sudo
结合使用
sudo -u USER tee /path/to/file <<EOF
${variable}
EOF
答案 4 :(得分:15)
如果目标文件需要root权限,请使用|sudo tee
代替>
:
cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* be interpreted.
EOF
答案 5 :(得分:11)
对于可能遇到此问题的未来人员,以下格式有效:
(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
答案 6 :(得分:2)
例如你可以使用它:
首先(进行ssh连接):
while read pass port user ip files directs; do
sshpass -p$pass scp -o 'StrictHostKeyChecking no' -P $port $files $user@$ip:$directs
done <<____HERE
PASS PORT USER IP FILES DIRECTS
. . . . . .
. . . . . .
. . . . . .
PASS PORT USER IP FILES DIRECTS
____HERE
秒(执行命令):
while read pass port user ip; do
sshpass -p$pass ssh -p $port $user@$ip <<ENDSSH1
COMMAND 1
.
.
.
COMMAND n
ENDSSH1
done <<____HERE
PASS PORT USER IP
. . . .
. . . .
. . . .
PASS PORT USER IP
____HERE
第三(执行命令):
Script=$'
#Your commands
'
while read pass port user ip; do
sshpass -p$pass ssh -o 'StrictHostKeyChecking no' -p $port $user@$ip "$Script"
done <<___HERE
PASS PORT USER IP
. . . .
. . . .
. . . .
PASS PORT USER IP
___HERE
Forth(使用变量):
while read pass port user ip fileoutput; do
sshpass -p$pass ssh -o 'StrictHostKeyChecking no' -p $port $user@$ip fileinput=$fileinput 'bash -s'<<ENDSSH1
#Your command > $fileinput
#Your command > $fileinput
ENDSSH1
done <<____HERE
PASS PORT USER IP FILE-OUTPUT
. . . . .
. . . . .
. . . . .
PASS PORT USER IP FILE-OUTPUT
____HERE
答案 7 :(得分:0)
我喜欢在缩进的脚本中实现简洁,可读性和呈现的方法:
<<-End_of_file >file
→ foo bar
End_of_file
→
是选项卡字符。
答案 8 :(得分:0)
如果您要使Heredoc缩进以提高可读性:
$ perl -pe 's/^\s*//' << EOF
line 1
line 2
EOF
Bash中支持缩进的Heredoc的内置方法仅支持前导制表符,而不支持空格。
可以用awk替换Perl以节省一些字符,但是如果您了解基本的正则表达式,可能更容易记住Perl。