Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!dali.cs.montana.edu!caen!spool.mu.edu!agate!darkstar!cats.ucsc.edu!jik From: jik@cats.ucsc.edu (Jonathan I Kamens) Newsgroups: comp.unix.shell Subject: Re: cat, pipes, and filters Keywords: cat pipe filter Message-ID: <16438@darkstar.ucsc.edu> Date: 31 May 91 19:19:33 GMT References: <1991May31.165446.1530@progress.com> Sender: usenet@darkstar.ucsc.edu Organization: University of California, Santa Cruz Lines: 30 In article <1991May31.165446.1530@progress.com>, root@progress.COM (Root of all Evil) writes: |> cat $FILE | sed s/"$ENTRY"/"$NEWENTRY"/ > $FILE |> |> cat $FILE | sed s/"$ENTRY"/"$NEWENTRY"/ | cat > $FILE In this case, you're using shell redirection to output to the file. Shell redirection takes place before any of the commands on the command line actually get run. Therefore, the shell opens $FILE and truncates it in preparation for sending output to it *before* the "cat" at the beginning of the pipeline opens it in order to read it. |> cat $FILE | sed s/"$ENTRY"/"$NEWENTRY"/ | tee $FILE 1>/dev/null In this case, cat gets started and opens the file in order to read it, and *then* tee gets started, sees that it's supposed to send output to $FILE, and opens the file and truncates it in preparation for sending output to it. Once cat has opened the file for read, it gets to read it, because the file that tee is sending output to is (in effect) a "different file" from the kernel's point of view. |> So now my script works but I don't really understand why. I've tested |> this on SunOs 4.1 and Interactive SysV 2.2, no difference. Is there |> something simple about pipes or I/O redirection that I'm not grasping? |> Or is this a feature of cat? Quoting from the man page cat(1): NOTES Beware of `cat a b > a' and `cat a b > b', which destroy the input files before reading them.