首页 文章

如何在Bash脚本中将heredoc写入文件?

提问于
浏览
594

如何在Bash脚本中将此文档写入文件?

8 回答

  • 114

    我喜欢这种方法在缩进脚本中简洁,可读和呈现:

    <<-End_of_file >file
    →       foo bar
    End_of_file
    

    其中 是制表符 .

  • 44

    例如,您可以使用它:

    First(making ssh connection):

    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
    

    Second(executing commands):

    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
    

    Third(executing commands):

    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(using variables):

    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
    
  • 20

    Note:

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

    • 是否要覆盖现有文件,附加到现有文件或写入新文件?

    • 您的用户或其他用户(例如 root )是否拥有该文件?

    • 你想在字面上写下你的heredoc的内容,还是要在你的heredoc里面用bash解释变量引用?

    (还有其他维度/子问题,我对 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
    
  • 15

    要构建@Livven的answer,这里有一些有用的组合 .

    • 变量替换,保留前导选项卡,覆盖文件,回显到stdout
    tee /path/to/file <<EOF
    ${variable}
    EOF
    
    • no variable substitution ,保留前导标签,覆盖文件,回显到标准输出
    tee /path/to/file <<'EOF'
    ${variable}
    EOF
    
    • 变量替换, leading tab removed ,覆盖文件,回显到stdout
    tee /path/to/file <<-EOF
        ${variable}
    EOF
    
    • 变量替换,保留前导标签, append to file ,echo到stdout
    tee -a /path/to/file <<EOF
    ${variable}
    EOF
    
    • 变量替换,保留前导选项卡,覆盖文件, no echo to stdout
    tee /path/to/file <<EOF >/dev/null
    ${variable}
    EOF
    
    • 以上也可以与 sudo 结合使用
    sudo -u USER tee /path/to/file <<EOF
    ${variable}
    EOF
    
  • 2

    阅读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脚本中,您可能希望使用缩进来使代码可读,但是这会使您在此文档中缩进文本产生不良影响 . 在这种情况下,使用 <<- (后跟短划线)来禁用前导标签( Note 用于测试,您需要 replace the leading whitespace with a tab character ,因为我无法在此处打印实际的标签字符 . )

    #!/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
    
  • 0

    而不是使用 cat 和I / O重定向,而不是使用 tee 可能是有用的:

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

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

  • 12

    需要root权限时

    如果目标文件需要root权限,请使用 |sudo tee 而不是 >

    cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
    The variable $FOO will *not* be interpreted.
    EOF
    
  • 826

    对于可能遇到此问题的未来人员,以下格式有效:

    (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
    

相关问题