From: Jose Luis on 13 Nov 2009 02:37 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>> Thanks in advance, Jose Luis
From: Stephane CHAZELAS on 13 Nov 2009 06:03 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. 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: Alan Curry on 13 Nov 2009 06:24 In article <04eefdf7-ddea-41de-86f5-ffc6f15e31b3(a)37g2000yqm.googlegroups.com>, Jose Luis <jose.luis.fdez.diaz(a)gmail.com> wrote: >Hi, > >Does the shell create a process to run "tee" command? Of course. > >Can the code below print "not found"? No. Well, yes, but not for the reason you think. > ><<snip begin>> >#!/usr/bin/ksh > >cat | tee foo >/dev/null <<EOF >one >two >three >EOF First, your redirections are messed up. The <<EOF needs to be on the left side of the pipe if you want the heredoc to be the stdin of cat. The way you have it now, tee is reading the heredoc and cat is reading the script's original stdin (probably your tty). But let's assume you fixed that. The command "cat | tee foo" is run with some redirections. The shell creates 2 child processes connected by a pipe (and the heredoc itself is probably implemented using an additional 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. It waits until both of them are finished, because that's how the shell normally does things. One command, then the next. Unless you put it in the background. The tee process won't exit until it's done writing all of its output. If it failed writing to the file (disk full or some such disaster) it will tell you on stderr. In that case you might get a "not found" below. If you don't like that, look up "set -e". After the 2 child processes have exited, the shell moves on to the grep: > >if grep "three" foo 2>&1 By this point, the tee process is done and gone. If it didn't successfully write to foo, it has at least complained on stderr. There's no race here. >then print "found" >else print "not found" > ><<snip end>> Missing "fi". And I don't get the point of the 2>&1 either. -- Alan Curry
From: Stephane CHAZELAS on 13 Nov 2009 08:15 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) > 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. -- St�phane
From: Kaz Kylheku on 13 Nov 2009 13:10 On 2009-11-13, Jose Luis <jose.luis.fdez.diaz(a)gmail.com> wrote: > 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 Surely, you mean tee foo >/dev/null <<EOF one two three EOF You have a useless-and-wrong-use-of-cat. To convert it to a useless-use-of-cat, you are looking for this: cat <<EOF | tee foo >/dev/null one two three EOF See the << here-doc redirection actually has to be, like, on the command which is to get that redirection. If you want the here-doc to go into cat, then <<EOF has to be in cat's command line.
|
Next
|
Last
Pages: 1 2 Prev: about IFS="\n" Next: Possible to define a variable for only certain directories? |