ヒアドキュメントを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
これはより簡潔です。また、リダイレクトオペレーターとは異なり、sudo
root権限でファイルに書き込む必要がある場合に組み合わせることができます。
> /dev/null
hereファイルの内容が作成時に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.conf
cat << 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
____HERE
2番目(コマンドを実行):
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
3番目(コマンドを実行):
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(変数を使用):
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