The proper way to keep a
here document from expanding variables and command substitutions is simply to quote the opening string.
Also, if you use "
<<-", then you can safely indent the content, and even the closing string if you want to, with
tabs (and only tabs). They will be removed upon evaluation and won't appear in the final output.
Code:
#the heredoc contents are tab indented
cat >Hutespot.pbs <<-'EOF'
#!/bin/bash
#PBS -l nodes=64:ppn=1,pvmem=1900mb,walltime=1:00:00
#PBS -V
cd "$PBS_O_WORKDIR"
mpirun "$HOME/bin/kkr.run" "$job.inp" >> "$job.out"
EOF
Of course, this will disable
all variable expansions, so if you need some of them to expand and some not to, then you'll have to escape them individually, as you've already discovered.
It's more appropriate to use
$HOME in scripts than "
~". The latter is a kind of convenience alias designed more for interactive use, and is more limited than the preset shell variable.
QUOTE ALL OF YOUR VARIABLE EXPANSIONS. Note that the quotes inside the heredoc will not be directly evaluated, but will be passed literally to the target location, to be properly evaluated when the script is actually executed.
Finally, and this is just a bit of stylistic advice, I also recommend dropping the brackets around your variables. The full "
${var}" form is usually unneeded (with some exceptions), and does nothing but add extra typing and clutter to your code, which can lead to an increased chance of errors. Take it from someone who's been there, you're better off without them.