EOF後に$ idが消えるのはなぜですか?

EOF後に$ idが消えるのはなぜですか?
cat >run_pos2bed3.sh <<EOF
ls 2*/peaks.txt | while read id;
do echo $id done;
EOF

入力後

ナノ専用ショー

ls 2*/peaks.txt | while read id;
do echo  done;
EOF

$id後でどのように追加しますかEOF

答え1

それ以来、なぜ$id消えたのですかEOF

<<なぜなら、 と を言うと$変数がすでに持っている値を得ることになるからです。そうすれば

id=foo
cat >run_pos2bed3.sh <<EOF
ls 2*/peaks.txt | while read id;
do echo $id done;
EOF

あなたはそれを得るために見つけることができますdo echo foo done

$id後でどのように追加しますかEOF

する

cat >run_pos2bed3.sh << \EOF
ls 2*/peaks.txt | while read id;
do echo $id done;
EOF

違いはオンラインに接続する前です\EOF<<

答え2

この文書の内容は、その文書を参照しない限り、拡張(変数とコマンドの置き換え)にすることができます。あなたの場合、ここの文書は引用されていないので$id拡張されました。ドキュメントがリダイレクトされると、変数が設定されない可能性が高いため、その値は空の文字列に展開されます。これは変数が「消える」ように見えます。

代わりに:

cat >run_pos2bed3.sh <<'END_SCRIPT'
ls 2*/peaks.txt |
while read id; do
    echo "$id"
done
END_SCRIPT

または、より安全なスクリプト(id変数が実際に必要でない場合)の場合

cat >run_pos2bed3.sh <<'END_SCRIPT'
printf '%s\n' 2*/peaks.txt
END_SCRIPT

'END_SCRIPT'ここにある文書を引用するのは、内部の一重引用符です("END_SCRIPT"またはで書くこともできます\END_SCRIPT)。

$idまた、良いシェルスクリプトの練習に必要な拡張機能をドキュメント自体で参照しました(例:いつ二重引用符が必要ですか?)。

関連情報