11

I have the following code in a batch script:

mpirun -np 6 ./laplace <<END
100
100
100
0.01
100
3
2
1
END
| tail -n 1 > output

But it isn't working. What I want it to do is to use the HERE file as input to the mpirun command, and then pipe the output to the tail command. However, I think the HERE file and tail output things are getting confused.

How should I write this so that it does what I want?

2 Answers 2

11

What you've written in the first line looks like a complete command (a “(compound) list” in shell terminology), so the shell treats it as a complete command. Since there's a here-document start marker (<<END), the shell then reads the here-document contents, and then starts a new command. If you want to put the here-document in the middle of a list, you need to indicate to the shell that the list is not finished. Here are couple of ways.

mpirun -np 6 ./laplace <<END |
…
END
tail -n 1 > output
{ mpirun -np 6 ./laplace <<END
…
END
} | tail -n 1 > output

Or, of course, you can make sure the command completely fits in the first line.

mpirun -np 6 ./laplace <<END | tail -n 1 > output
…
END

The rule to remember is that the here-document contents starts after the first unquoted newline after the <<END indicator. For example, here's another obfuscated way of writing this script:

mpirun -np 6 ./laplace <<END \
| tail -n $(
…
END
             echo 1) > output
2
  • That last one! "obfuscated".. You're not kidding! :) .. I had stumbled across the hard-newline idea, but to actually bisect a bracketed block like that is verging on the bizzare.. Is this by design, or is it a coincidental abberation?. (eg. is there a real use for this? ... and you can actually even put multiple semi-colon seperated commands in that first "soft" line..
    – Peter.O
    May 26, 2011 at 15:10
  • @fred: Just a coincidental aberration. There has to be some rule as to where the heredoc starts and stops. Here the rule is that the heredoc is like a single token attached to the next newline token after the <<END bit. A backslash-newline nullifies the newline. May 26, 2011 at 20:06
7
mpirun -np 6 ./laplace <<END | tail -n 1 > output
100
100
100
0.01
100
3
2
1
END

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .