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

after input it

nano only show

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

How can I add $id after EOF?

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
MING LU
  • 11

2 Answers2

3

Why did $id disappear after the EOF?

Because, when you say << and then $, you get the value that the variable already has.  If you do

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

you'll see that you get do echo foo done.

How can I add $id after EOF?

Do

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

The difference is the \ before the EOF on the << line.

  • 2
    You can also use quotes: << 'EOF'. All documented at https://www.gnu.org/software/bash/manual/bashref.html#Here-Documents – glenn jackman Oct 18 '17 at 00:49
0

The contents of a here-document will undergo expansion (of variables and command substitutions) unless the document is quoted. In your case, the here-document is unquoted, so $id is expanded. It is likely that the variable was unset when the document was redirected, so its value is expanded to an empty string. This makes it appear as if the variable "disappeared".

Instead:

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

or, for a safer script (the id variable is actually not needed),

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

It's the single quotes in 'END_SCRIPT' that makes the here-document quoted (this could also be written as either "END_SCRIPT" or \END_SCRIPT).

I've also quoted the expansion of $id within the document itself, as is required by good shell scripting practices (see e.g. When is double-quoting necessary?).

Kusalananda
  • 333,661