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


当前回答

对于那些寻找纯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写入文件”的问题。

其他回答

对于那些寻找纯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

此外,如果您正在写入一个文件,检查写入是否成功或失败可能是一个好主意。例如:

if ! echo "contents" > ./file ; then
    echo "ERROR: failed to write to file" >& 2
    exit 1
fi

要对heredoc进行同样的操作,有两种可能的方法。

1)

if ! cat > ./file << EOF
contents
EOF
then
    echo "ERROR: failed to write to file" >& 2
    exit 1
fi

if ! cat > ./file ; then
    echo "ERROR: failed to write to file" >& 2
    exit 1
fi << EOF
contents
EOF

您可以通过将目标文件./file替换为/file(假设您不是以根用户身份运行)来测试上述代码中的错误情况。

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

(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