Reading a pipe is destructive; there is no way to seek on a pipe:
ESPIPE (29): Illegal seek
The error number is from MacOS X, but the name is traditional (and POSIX-mandated) and gives an indication of where the restriction comes from.
So, if you want to reprocess input in a shell script, you will need to stash the standard input away in a file so you can reprocess it:
tmp=${TMPDIR:-/tmp}/xx.$$ # Consider mktemp or something
trap "rm -f $tmp.1; exit 1" 0 1 2 3 13 15 # Exit, HUP, INT, QUIT, PIPE, TERM
tee $tmp.1 |
while read -a linA
do
...
done
...reprocess $tmp.1 here...
rm -f $tmp.1
trap 0
exit $exit_status
The only trap to watch is that because of the pipeline, variables set in the while
loop are not accessible in the parent shell. If that's a problem, you can use:
tee $tmp.1 |
{
while read -a linA
do
...
done
...reprocess $tmp.1 here...
}
The braces group the statements for I/O redirection purposes. The tee
process will have completed because of EOF so the file will be complete when the while read
detects EOF, so it is safe to access $tmp.1
after the loop.
The one thing to watch is that tee
will make this unresponsive to terminal input. Files won't be a problem; piped input is unlikely to be a problem. However, tee
will probably fully buffer its output, rather than line buffering its output, so the read loop may not see anything until you've typed many lines of input.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…