code

Bash 스크립트의 파일에 heredoc을 어떻게 작성할 수 있습니까?

codestyles 2020. 9. 30. 10:46
반응형

Bash 스크립트의 파일에 heredoc을 어떻게 작성할 수 있습니까?


Bash 스크립트의 파일에 here 문서를 어떻게 쓸 수 있습니까?


고급 Bash 스크립팅 가이드 19 장 . 여기 문서를 읽어보십시오 .

다음은 파일에 내용을 기록하는 예입니다. /tmp/yourfilehere

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

마지막 'EOF'(The LimitString)는 단어 LimitString가 인식되지 않음을 의미하므로 단어 앞에 공백이 없어야합니다 .

쉘 스크립트에서 들여 쓰기를 사용하여 코드를 읽을 수 있도록 할 수 있지만, 이것은 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

... 또는 다음을 사용하여 heredoc을 파일에 작성합니다 sudo.

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

대신 사용 cat및 I / O를 재 지정이 사용하기 유용 할 수 있습니다 tee대신 :

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

It's more concise, plus unlike the redirect operator it can be combined with sudo if you need to write to files with root permissions.


Note:

The question (how to write a here document (aka heredoc) to a file in a bash script?) has (at least) 3 main independent dimensions or subquestions:

  1. Do you want to overwrite an existing file, append to an existing file, or write to a new file?
  2. Does your user or another user (e.g., root) own the file?
  3. Do you want to write the contents of your heredoc literally, or to have bash interpret variable references inside your heredoc?

(There are other dimensions/subquestions which I don't consider important. Consider editing this answer to add them!) Here are some of the more important combinations of the dimensions of the question listed above, with various different delimiting identifiers--there's nothing sacred about EOF, just make sure that the string you use as your delimiting identifier does not occur inside your heredoc:

  1. 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
    
  2. 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
    
  3. 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
    
  4. 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
    
  5. 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
    
  6. 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
    

To build on @Livven's answer, here are some useful combinations.

  1. variable substitution, leading tab retained, overwrite file, echo to stdout

    tee /path/to/file <<EOF
    ${variable}
    EOF
    
  2. no variable substitution, leading tab retained, overwrite file, echo to stdout

    tee /path/to/file <<'EOF'
    ${variable}
    EOF
    
  3. variable substitution, leading tab removed, overwrite file, echo to stdout

    tee /path/to/file <<-EOF
        ${variable}
    EOF
    
  4. variable substitution, leading tab retained, append to file, echo to stdout

    tee -a /path/to/file <<EOF
    ${variable}
    EOF
    
  5. variable substitution, leading tab retained, overwrite file, no echo to stdout

    tee /path/to/file <<EOF >/dev/null
    ${variable}
    EOF
    
  6. the above can be combined with sudo as well

    sudo -u USER tee /path/to/file <<EOF
    ${variable}
    EOF
    

When root permissions are required

When root permissions are required for the destination file, use |sudo tee instead of >:

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

For future people who may have this issue the following format worked:

(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

As instance you could use it:

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

I like this method for concision, readability and presentation in an indented script:

<<-End_of_file >file
→       foo bar
End_of_file

Where →        is a tab character.

참고URL : https://stackoverflow.com/questions/2953081/how-can-i-write-a-heredoc-to-a-file-in-bash-script

반응형