ヒアドキュメントをBashスクリプトのファイルに書き込むにはどうすればよいですか?
ヒアドキュメントをBashスクリプトのファイルに書き込むにはどうすればよいですか?
回答:
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'(The 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
<<<、彼らは何と呼ばれていますか?
                    <<<は「ヒア文字列」と呼ばれます。のようなコードtr a-z A-Z <<< 'one two three'は文字列になりますONE TWO THREE。詳細については、en.wikipedia.org
                    <<'EOF'あり<<EOFます。
                    代わりに使用するcatと、I / Oリダイレクション使用すると便利かもしれませんtee代わりに:
tee newfile <<EOF
line 1
line 2
line 3
EOF
これはより簡潔です。また、リダイレクトオペレーターとは異なり、sudoroot権限でファイルに書き込む必要がある場合に組み合わせることができます。
> /dev/nullhereファイルの内容が作成時にstdoutに表示されないように、最初の行の末尾に追加することをお勧めします。
                    sudoはその簡潔さのためではなく、との互換性のために私にアピールしました:-)
                    man tee。-a上書きする代わりにフラグを使用して追加します。
                    注意:
質問(hereドキュメント(別名heredoc)をbashスクリプトのファイルに書き込む方法は?)には、(少なくとも)3つの主要な独立した次元またはサブ質問があります。
root:)がファイルを所有していますか?(私が重要とは思わない他の次元/サブ質問があります。それらを追加するには、この回答を編集することを検討してください!)ここに、さまざまな区切り識別子を使用して、上記の質問の次元のより重要な組み合わせのいくつかを示します-何もありません神聖なEOF、あなたの区切り識別子として使用する文字列があなたのヒアドキュメント内に出現しないことを確認してください:
所有している既存のファイルを上書きする(または新しいファイルに書き込む)には、ヒアドキュメント内の変数参照を置き換えます。
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
所有している既存のファイルを追加する(または新しいファイルに書き込む)には、ヒアドキュメント内の変数参照を置き換えます。
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
ヒアドキュメントのリテラル内容で、所有している既存のファイルを上書きする(または新しいファイルに書き込む)には:
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
ヒアドキュメントのリテラル内容を使用して、所有している既存のファイルを追加する(または新しいファイルに書き込む)には:
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
ルートが所有する既存のファイルを上書きする(または新しいファイルに書き込む)には、ヒアドキュメント内の変数参照を置き換えます。
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
ヒアドキュメントのリテラル内容を使用して、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
-a==を省略し--appendます。つまり、tee -a-> teeです。参照してくださいinfo tee。(私はそれをここに引用したいが、コメントのマークアップがあまりにも限られている
                    sudo tee /path/to/your/file << 'Screw_you_Foo'ますか?
                    FOE代わりにEOF?
                    @Livvenの答えに基づいて、いくつかの便利な組み合わせを示します。
変数置換、先頭のタブを保持、ファイルを上書き、標準出力にエコー
tee /path/to/file <<EOF
${variable}
EOF変数置換なし、先頭のタブは保持、ファイルを上書き、標準出力にエコー
tee /path/to/file <<'EOF'
${variable}
EOF変数の置換、先頭のタブの削除、ファイルの上書き、標準出力へのエコー
tee /path/to/file <<-EOF
    ${variable}
EOF変数置換、先頭のタブを保持、ファイルに追加、標準出力にエコー
tee -a /path/to/file <<EOF
${variable}
EOF変数置換、先頭タブ保持、ファイル上書き、標準出力へのエコーなし
tee /path/to/file <<EOF >/dev/null
${variable}
EOF上記と組み合わせることができるsudoだけでなくとして
sudo -u USER tee /path/to/file <<EOF
${variable}
EOF宛先ファイルにroot権限が必要な場合は、|sudo tee代わりにを使用して>ください:
cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* 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.confcat << END > afile。ヒアドキュメントが続くと、完全にうまく機能します。
                    cat受け入れられた回答に示されているように、出力リダイレクトは、行の終わりで始まる必要があります。
                    catがサブシェルの内部で実行され、サブシェルのすべての出力はファイルにリダイレクトされます
                    インスタンスとしてそれを使用できます:
最初(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
____HERE2番目(コマンドを実行):
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    
____HERE3番目(コマンドを実行):
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  
___HEREForth(変数を使用):
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