2

I have a script that outputs various information and the text fields of an html form (method POST). When I attempt to cat <&0, it displays properly. However a few lines down, I try to cat <&0 again and nothing is printed. What am I doing wrong?

....
cat <&0
echo Content length is $CONTENT_LENGTH
cat <&0 | sed -e 's/&/\n/g' | cut -d'=' -f2

....
4
  • Could you explain what your script is actually doing? I mean, why do you want to cat <&0 in the first place?
    – terdon
    Commented Nov 6, 2014 at 21:32
  • 1
    Why do you write cat <&0 instead of just cat? Commented Nov 6, 2014 at 21:33
  • <&0 only duplicates (redundantly and idempotently) the file descriptor, not the data available on that descriptor.
    – chepner
    Commented Nov 6, 2014 at 21:34
  • The purpose is I just want to display the submitted text from a HTML form (POST).
    – swam
    Commented Nov 6, 2014 at 21:39

2 Answers 2

10

You are doing nothing wrong: this is what we should expect.

The first cat <&0 consumes the entire contents of standard input because that's what cat does: it reads all of its input until the end.

When the second cat <&0 runs, there is nothing left to consume on standard input: the end of file was already reached previously.

If, in a shell script, you need to make 2 or more passes through your standard input, you have to dump it into a temp file, then process the temporary file as many times as you want.

Securely creating temporary files in /tmp and making sure they are correctly disposed of when your script terminates or dies is left as an exercise for you :-)

By the way, the <&0 is unnecessary and does nothing. Its function is to point standard input to file descriptor 0... which is standard input... which is by definition where standard input already points! You can just make that command cat alone instead.

5

If you want to read from standard input twice, you need to buffer it somehow (most likely, in a temporary file). The first cat can be replaced by a call to tee which also writes the data to a file, which can be reread by the second call to cat (which is not necessary either; sed can read from the file directly).

tee > input_buffer  # Copy standard input to a file and standard output
echo Content length is $CONTENT_LENGTH
sed -e 's/&/\n/g' input_buffer | cut -d = -f2 

You must log in to answer this question.

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