我如何在这里写一个文档到Bash脚本文件?
当前回答
使用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
对于那些寻找纯bash解决方案(或需要速度)的人来说,这里有一个简单的解决方案,没有cat:
# here-doc tab indented
{ read -r -d '' || printf >file '%s' "$REPLY"; } <<-EOF
foo bar
EOF
或简单的“mycat”函数(并避免在环境中留下REPLY):
mycat() {
local REPLY
read -r -d '' || printf '%s' "$REPLY"
}
mycat >file <<-EOF
foo bar
EOF
快速比较“mycat”vs OS cat(1000循环>/dev/null在我的OSX笔记本电脑上):
mycat:
real 0m1.507s
user 0m0.108s
sys 0m0.488s
OS cat:
real 0m4.082s
user 0m0.716s
sys 0m1.808s
注意:mycat不处理文件参数,它只处理“将heredoc写入文件”的问题。
例如,你可以使用它:
首先(进行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
第二个(executing的聚会):
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
(使用变量)。
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
对于将来可能遇到这个问题的人,下面的格式是有效的:
(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
当需要root权限时
当目标文件需要root权限时,使用|sudo tee而不是>:
cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* be interpreted.
EOF
cat << "EOF" |sudo tee /tmp/yourprotectedfilehere
The variable $FOO *will* be interpreted.
EOF
推荐文章
- 检查bash变量是否等于0
- 只使用md5sum获取哈希值(没有文件名)
- 如何生成一个核心转储在Linux上的分段错误?
- 在Bash中测试非零长度字符串:[-n "$var"]或["$var"]
- 如何删除超过X小时的文件
- 如何创建Bash别名?
- 将所有变量从一个shell脚本传递到另一个?
- 如何删除shell脚本中文件名的扩展名?
- 使用xargs调用shell函数
- 如何限制从grep返回的结果的数量?
- 'find -exec'是Linux中的shell函数
- 将值从管道读入shell变量
- 在Bash中重用上一个命令的输出
- RE错误:在Mac OS X上的非法字节序列
- 对bash脚本函数中定义的变量使用curl POST