From: Alan Curry on
In article <slrnhfqmuv.8co.stephane.chazelas(a)spam.is.invalid>,
Stephane CHAZELAS <stephane_chazelas(a)yahoo.fr> wrote:
>2009-11-13, 11:24(+00), Alan Curry:
>[...]
>> The command "cat | tee foo" is run with some redirections. The shell creates
>> 2 child processes connected by a pipe
>
>Note that POSIX doesn't mandate the use of pipes for connecting
>cat's stdout to tee's stdin, and as I just found out, recent
>versions of ksh93 may use unix domain sockets instead (causing
>all sorts of problems).
>
>> (and the heredoc itself is probably
>> implemented using an additional pipe)
>
>here docs are implemented with temporary files. POSIX
>doesn't mandate it, so future shells (like future versions of
>ksh93) might change that, causing all sorts of problems again
>(for instance for scripts that assume you can lseek on a
>here-document)

I saw the #! ksh in the original script, but I chose to ignore it since it
didn't really matter for the main question. Tested with my usual sh (ash), it
used a pipe, so I figured that was normal. Taking another look now, ash is
the only shell I can find that does use a pipe.

>
>> The file descriptors are put in the
>> right places and then one child execs cat while the other execs tee. The
>> shell then waits until both of them are finished.
>[...]
>
>Some (like ksh93t+ on debian) will only wait for tee.

Now that is surprising. You mean "sleep 30 | grep ." will return instantly?
How can anyone tolerate such weirdness?

--
Alan Curry
From: Alan Curry on
In article <hdknap$68l$1(a)aioe.org>, I wrote:
>In article <slrnhfqmuv.8co.stephane.chazelas(a)spam.is.invalid>,
>Stephane CHAZELAS <stephane_chazelas(a)yahoo.fr> wrote:
>>Some (like ksh93t+ on debian) will only wait for tee.
>
>Now that is surprising. You mean "sleep 30 | grep ." will return instantly?
>How can anyone tolerate such weirdness?

After further reflection (and actual testing), that should have been
sleep 30 | grep . </dev/null

and it does return immediately. Oh that's weird.

Also interesting:
sleep 30 | true # this one actually sleeps!
sleep 30 | /bin/true # back to the weirdness.

I'm glad I use a sane shell with a $pipestatus instead of this krazy stuff.

--
Alan Curry
From: Jose Luis on
On Nov 13, 12:03 pm, Stephane CHAZELAS <stephane_chaze...(a)yahoo.fr>
wrote:
> 2009-11-12, 23:37(-08), Jose Luis:
>
> > Hi,
>
> > Does the shell create a process to run "tee" command?
>
> > Can the code below print "not found"?
>
> > <<snip begin>>
> > #!/usr/bin/ksh
>
> > cat | tee foo >/dev/null <<EOF
> > one
> > two
> > three
> > EOF
>
> > if grep "three" foo 2>&1
> > then print "found"
> > else print "not found"
>
> > <<snip end>>
>
> [...]
>
> Note that:
>
> cat | tee foo << X
>
> is not the same as
>
> cat << X | tee foo
>
> in a pipeline, shells are required (by POSIX) to wait for the
> rightmost command but not for the others. Some shells including
> some implementations/versions of ksh will and some will not.

Thanks for your help.

So, the script below can print "not found", can't it?

<<snip begin>>

cat <<EOF | tee foo |grep "xxxxx" >/dev/null
one
two
three
EOF

if grep "three" foo 2>&1
then print "found"
else print "not found"
fi

<<snip end>>


Regards,
Jose Luis



>
> The cat command is run with its stdin unchanged and its stdout
> pointing to a pipe whose other end has been closed (because
> tee's input has been redirected to something else).
>
> If cat reads anything from it's stdin, it will be killed by a
> SIGPIPE has soon as it writes it to stdout. Otherwise, it will
> run until it finds the end of file on its stdin, in background
> if the shell doesn't wait for it, or in foreground otherwise. If
> it's stdin is a terminal, it may end up being suspended or
> killed (or the read failing and thus terminate with an error) if
> its process group is put in the background (of the terminal)
> later on.
>
> In any case, tee will run with its stdin connected to a
> temporary file containing the here document, and its stdout
> connected to /dev/null and every shell will wait for its
> termination, so unless "foo" is not writable for some reason, or
> any other abnormal condition such as the shell not being able to
> create the temp file or not finding the tee command, tee will
> always write those lines to "foo"
>
> > Does the shell create a process to run "tee" command?
>
> Unless tee is built in the shell, the "tee" command will have to
> run in a separate process as the shell running the script of
> course. A process can't run too commands at the same time.
>
> --
> Stéphane

From: Bill Marcum on
On 2009-11-16, Jose Luis <jose.luis.fdez.diaz(a)gmail.com> wrote:
> So, the script below can print "not found", can't it?
>
><<snip begin>>
>
> cat <<EOF | tee foo |grep "xxxxx" >/dev/null
> one
> two
> three
> EOF
>
> if grep "three" foo 2>&1
> then print "found"
> else print "not found"
> fi
>
><<snip end>>
>
It can print "not found" if it doesn't have permission to write foo or
the current directory, but then "tee foo" should print an error message.