programing

Bash 스크립트로 파일에 대한 세레독을 작성하려면 어떻게 해야 합니다.

firstcheck 2023. 4. 8. 16:25
반응형

Bash 스크립트로 파일에 대한 세레독을 작성하려면 어떻게 해야 합니다.

여기 문서를 Bash 스크립트로 파일에 쓰려면 어떻게 해야 합니까?

Advanced Bash-Scripting Guide 챕터19 를 참조해 주세요. 문서.

는 '하다'에 있는 예입니다./tmp/yourfilehere

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

'EOF'라 함)는 해 주십시오.LimitString. 이 공백이 하기 때문입니다.것은,, 、 「 」LimitString인식되지 않습니다.

셸 스크립트에서 들여쓰기를 사용하여 코드를 읽을 수 있도록 할 수 있지만, 이 경우 문서의 텍스트를 들여쓰게 되는 바람직하지 않은 영향을 미칠 수 있습니다. 「」를 합니다.<<-(뒤에 대시 표시)를 사용하여 선행 탭을 비활성화합니다(여기서는 실제 탭 문자를 인쇄할 수 없기 때문에 테스트하려면 선행 공백을 탭 문자로 대체해야 합니다).

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

명령 파이프라인을 통해 세습관을 연결하려면:

cat <<'EOF' |  sed 's/a/b/'
foo
bar
baz
EOF

출력:

foo
bbr
bbz

파일을 ...을합니다. 또는 다음 명령을 사용하여 파일에 세레독을 씁니다.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

간결하고, '보다 낫다'와 할 수 .sudo루트 、 는는는는는파경 。

주의:

질문(여기 문서(일명 세레독)를 bash 스크립트로 파일에 쓰는 방법)(적어도) 3가지 주요 독립적 차원 또는 하위 질문이 있습니다.

  1. 기존 파일을 덮어쓰거나 기존 파일에 추가하거나 새 파일에 쓰시겠습니까?
  2. 사용자 또는 다른 사용자(예:root일을을 소유 ?? ????
  3. 당신은 유전자의 내용을 문자 그대로 쓰고 싶습니까, 아니면 bash가 유전자의 다양한 참조를 해석하게 하고 싶습니까?

(중요하지 않다고 생각되는 다른 측면/제안들이 있습니다.이 답변을 편집하여 추가해 주세요.의 차원에 보다 가 있습니다. 이 조합은 여러 가지 구분자로 구분됩니다. 이 조합에는 신성한 EOF구분 식별자로 사용하는 문자열이 세레독 내에서 발생하지 않는지 확인합니다.

  1. 사용자가 소유한 기존 파일을 덮어쓰거나 새 파일에 쓰려면 세레독 내의 변수 참조를 대체합니다.

    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. 사용자가 소유하고 있는 기존 파일을 추가하려면(또는 새 파일에 쓰려면) 세레독 내의 변수 참조를 대체하십시오.

    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. 소유한 기존 파일을 덮어쓰거나 새 파일에 쓰려면 세레독의 리터럴 내용을 사용합니다.

    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. 사용자가 소유한 기존 파일을 리터럴한 세습 내용과 함께 추가하려면(또는 새 파일에 쓰려면) 다음 절차를 수행합니다.

    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. 루트가 소유한 기존 파일(또는 새 파일에 쓰기)을 덮어쓰려면 세레독 내의 변수 참조를 대체합니다.

    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. 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
    

@Liven의 답변을 바탕으로 몇 가지 유용한 조합을 소개합니다.

  1. 변수 치환, 선행 탭 유지, 파일 덮어쓰기, stdout 에코

    tee /path/to/file <<EOF
    ${variable}
    EOF
    
  2. 변수 대체 없음, 선행 탭 유지, 파일 덮어쓰기, stdout에 에코

    tee /path/to/file <<'EOF'
    ${variable}
    EOF
    
  3. 변수 치환, 선행 탭 제거, 파일 덮어쓰기, stdout 에코

    tee /path/to/file <<-EOF
        ${variable}
    EOF
    
  4. 변수 치환, 선행 탭 유지, 파일에 추가, stdout에 에코

    tee -a /path/to/file <<EOF
    ${variable}
    EOF
    
  5. 변수 치환, 선행 탭 유지, 파일 덮어쓰기, stdout에 에코 없음

    tee /path/to/file <<EOF >/dev/null
    ${variable}
    EOF
    
  6. 할 수 sudo 부탁드립니다.

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

루트 권한이 필요한 경우

파일에 는, 「」를 합니다.|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

이 문제가 발생할 가능성이 있는 장래의 유저에게는, 다음의 포맷이 유효합니다.

(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

순수한 bash 솔루션(또는 속도를 필요로 하는 고객)을 위한 간단한 솔루션은 다음과 같습니다.

# 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과 OS cat의 빠른 속도 비교(1000루프>/dev/null) :

mycat:
real    0m1.507s
user    0m0.108s
sys     0m0.488s

OS cat:
real    0m4.082s
user    0m0.716s
sys     0m1.808s

메모: mycat은 파일 인수를 처리하지 않고 "파일에 세습 쓰기" 문제만 처리합니다.

예를 들어 다음과 같이 사용할 수 있습니다.

첫 번째(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

Fourth(변수 사용):

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

읽기 쉽도록 유전자를 들여쓰기를 원하는 경우:

$ perl -pe 's/^\s*//' << EOF
     line 1
     line 2
EOF

Bash에서 들여쓰기된 세습을 지원하기 위한 기본 제공 메서드는 공백이 아닌 선행 탭만 지원합니다.

Perl을 awk로 대체하여 몇 글자를 저장할 수 있지만 기본적인 정규 표현을 알고 있다면 Perl을 기억하기가 더 쉬울 것입니다.

또한 파일에 쓰는 경우 쓰기가 실패했는지 확인하는 것이 좋습니다.예를 들어 다음과 같습니다.

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

유전적으로도 같은 방법으로 접근하려면 두 가지 방법이 있습니다.

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(루트로 실행되고 있지 않은 경우).

다음과 같은 기본적인 리다이렉트 방법이 마음에 듭니다.인테드 스크립트에서의 대조도, 가독성, 프레젠테이션입니다.

<<-End_of_file >file
→       foo bar
End_of_file

어디에→       는 캐릭터입니다.

이것은 표준 Bourne 쉘 리다이렉트이며 포킹은 없습니다.cat또는tee과정.하지만 전류로는 작동하지 않습니다.bash을 통해 호출되어도/bin/sh아직 동작하고 있습니다./bin/zsh20년 이상 전부터요.

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

반응형