web-dev-qa-db-ja.com

ヒアドキュメントを使用してBashスクリプトからスクリプトを作成します。変数が置き換えられるのはなぜですか?

マスタースクリプトからスクリプトを作成しているときに問題が発生しました。

単純な:

cat  pippo << EOF
LOGFILE=test.log    
echo '#############################' >> $LOGFILE
EOF

。しかし、私がpippoを検査すると、次のようになります。

LOGFILE=test.log
echo '#############################' >>
EOF

$ LOGFILEが置き換えられたのはなぜですか?

6
giuseppe

ヒアドキュメントは、デフォルトでシェル拡張、正確にはパラメータ拡張、コマンド置換、および算術拡張の対象となります。したがって、あなたのケースでは変数(パラメーター)の展開が行われています-変数LOGFILEは現在のシェルで展開されており、変数はおそらく存在しないため、展開された値としてnullが返されます(そして置き換えられます) 。

ヒアドキュメントで文字通りシェルメタ文字を取得するには、ターミネータ文字列を引用符で囲みます。

cat pippo <<'EOF'  ## "EOF" would do too
LOGFILE=test.log    
echo '#############################' >>"$LOGFILE"
EOF

また、変数の展開は(おそらく)ファイル名を参照しているため、展開後にWordの分割やパス名の展開が行われないように引用してください。

10
heemayl

実際にpippoファイルを作成するには、次のことを行う必要があります。

cat > pippo <<EOF

これは、ヒアドキュメントの値をpippoという名前のファイルにリダイレクトします。

次に、ヒアドキュメント内のコンテンツを記述どおりにパイプし、展開、評価、変更しないようにするには、<<の後にWordを引用する必要があります。
これのいずれか(部分引用符でも機能します):

<<'EOF'
<<"EOF"
<<\EOF
<<E"O"F
<<E\OF

引用符がない場合、変数"$LOGFILE"の値は、環境ではnullのように見える値に展開され、失われます。

つまり、次のようなものを使用します。

cat > pippo << \_EOF_
LOGFILE=test.log    
echo '#############################' >> $LOGFILE
_EOF_
0
Isaac