Bashスクリプトでヒアドキュメントをファイルに書き込むにはどうすればいいですか?
Advanced Bash-Scripting Guideを読んでください 第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
)は、Wordの前に空白があってはいけません。これは、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
コマンドパイプラインを介してheredocをパイプ処理するには
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スクリプトでヒアドキュメント(別名heredoc)をファイルに書き込む方法)には、(少なくとも)3つの独立したディメンションまたはサブクエストがあります。
root
)がファイルを所有していますか?(私は重要ではないと思う他のディメンション/サブクエストがあります。それらを追加するためにこの答えを編集することを検討してください!) EOF
については神聖です。あなたの区切り識別子として使う文字列がnotがあなたのheredocの内側にあることを確認してください:
あなたが所有する既存のファイルを上書きする(または新しいファイルに書き込む)には、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
User = fooが所有する既存のファイルを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
@ Livvenの answer の上に構築するために、ここにいくつかの便利な組み合わせがあります。
変数置換、先頭のタブの保持、ファイルの上書き、標準出力へのエコー
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
例としてあなたはそれを使用することができます:
まず(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
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
私はインデントされたスクリプトで簡潔さ、読みやすさと提示のためにこのメソッドが好きです:
<<-End_of_file >file
→ foo bar
End_of_file
→
は tab キャラクター。