I/O redirection


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting I/O redirection
# 8  
Old 03-09-2011
Actually it now mostly makes sense. Notice the comment after the line in question.
Code:
ls -l 2>&1 >&3 3>&- | grep bad 3>&-    # Close fd 3 for 'grep' (but not 'ls').
#              ^^^^   ^^^^
#              1111   2222    3333

The item which I numbered 1111 closes fd 3, but the ls command had already made use of fd 3. So the process, which will become the ls command, uses fd 3, closes fd 3, and then forks. The child process, which will become grep, springs into existence with no fd 3. Why the author put in sequence number 3333 is not totally clear. But we are not really guaranteed that the grep process will be a child process of the ls process. If the shell was to be rewritten so that the grep process begat the ls process we would be closing fd 3 late. So while sequence 3 is unneccessary today it might be a hedge against a future revision to the shell or to make it more portable. Another possible reason for the superfluous sequence 3333 is to make it totally clear to the reader that grep process has no access to fd 3.

But in any event, the comment was meant to pertain to sequences 1111 and 2222. That's why the line is there.
# 9  
Old 03-09-2011
Quote:
Originally Posted by Perderabo
Code:
ls -l 2>&1 >&3 3>&- | grep bad 3>&-    # Close fd 3 for 'grep' (but not 'ls').
#              ^^^^   ^^^^
#              1111   2222    3333

With all due respect to your seniority and all the great, informative posts you have contributed long before I was even a gleam in the forum's eye, I believe your analysis of this pipeline and its redirections to be off the mark.

I will be using "the main shell" to refer to the shell tasked with interpreting the ls-grep pipeline.

Quote:
Originally Posted by Perderabo
But we are not really guaranteed that the grep process will be a child process of the ls process. If the shell was to be rewritten so that the grep process begat the ls process we would be closing fd 3 late.
The grep process will never be a child of the ls process. And, the ls process will never be a child of the grep process. They will be siblings, each a child of the main shell. Further, the order in which they are created does not matter.

For grep to beget ls would require more than a shell rewrite, it would require a grep one too.

Quote:
Originally Posted by Perderabo
So the process, which will become the ls command, uses fd 3, closes fd 3, and then forks.
Actually, the fork will happen before the i/o redirection, then an exec. If the i/o redirection were done before forking, file descriptor handling would get very very messy, as the parent would have to juggle things around before the fork, and then restore sanity afterwards (assuming the parent has further business to tend to).

As I understand it, the chain of events to realize the ls-grep pipeline is as follows:

The main shell will first create the descriptors that the pipe will use. Then, it will fork twice (creating two subshells). One of the subshells will eventually exec to become ls and the other will eventually exec to become grep.

One subshell will modify stdout to point to the pipe (this subshell will become ls) and the other will modify stdin (for grep). Before exec, these subshells have to process each command's command-line i/o redirections. In the case of the subshell that will become ls, this would make fd 1 a copy of fd 3 and would then close fd 3. In the case of the subshell to become grep, there's nothing to be done but close fd 3. Now, when each subshell exec's, there is no fd 3 available to either process.

Quote:
Originally Posted by Perderabo
The child process, which will become grep, springs into existence with no fd 3.
Agreed. The same is true of ls.

If I'm the one that's off the mark, I await the Cluestick of Enlightenment Smilie

Regards,
Alister

Last edited by alister; 03-09-2011 at 12:34 PM..
# 10  
Old 03-09-2011
Quote:
Originally Posted by alister
For grep to beget ls would require more than a shell rewrite, it would require a grep one too.
Not really true. I actually said that grep was the child and ls the parent. You made a slight goof and reversed my comments. But an experiment shows that the reversed statement you attributed to me is true. So I hereby adopt it as what I meant to say. Smilie
Code:
$ /bin/sleep 60 | grep bad &
[1]     32429
$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
xxxxx     3417  3416  0 Mar08 pts/1    00:00:00 -ksh
xxxxx    11703  3417  0 Mar08 pts/1    00:00:00 ksh
xxxxx    32424 11703  0 13:42 pts/1    00:00:00 ksh
xxxxx    32429 32424  0 13:43 pts/1    00:00:00 grep bad
xxxxx    32430 32429  0 13:43 pts/1    00:00:00 /bin/sleep 60
xxxxx    32431 32424  0 13:43 pts/1    00:00:00 ps -f
$

The grep process wound up as parent and the sleep process wound up as child. I would not want to bet that it always works that way. And no I don't have a special grep process that knew to establish the child.

32424 forked to create 32429 but both processes are still ksh because neither has exec'ed yet. 32429 then forked again to create a child 32430. At this point the whole pipeline exists and both processes exec'ed their respective programs.
# 11  
Old 03-09-2011
If I recall correctly, only the AT&T ksh and zsh run the last command in a pipeline in the current shell environment.

Edit: Irrelevant, see further comments.

Last edited by radoulov; 03-09-2011 at 06:25 PM..
This User Gave Thanks to radoulov For This Post:
# 12  
Old 03-09-2011
Quote:
Originally Posted by radoulov
If I recall correctly, only the AT&T ksh and zsh run the last command in a pipeline in the current shell environment:
Only if that command is a shell built-in. I did not know that zsh does that too. Now that bash supports co-processes this issue is the primary reason I don't want to switch to bash.

It's interest that bash is making the main shell the parent of each process in the pipeline. I guess it needs this to support it's PIPESTATUS concept. This must make hard to get the entire pipeline into a separate process group.


BTW, regarding the original question, my admittedly flawed, reasoning still might be what the author of that example was thinking. If not, then I not know what he was thinking. Anyone got a better idea on that?
# 13  
Old 03-09-2011
Quote:
Originally Posted by Perderabo
Only if that command is a shell built-in
[...]
Yes, of course, thanks for pointing it out.
# 14  
Old 03-09-2011
Quote:
Originally Posted by Perderabo
Code:
$ /bin/sleep 60 | grep bad &
[1]     32429
$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
xxxxx     3417  3416  0 Mar08 pts/1    00:00:00 -ksh
xxxxx    11703  3417  0 Mar08 pts/1    00:00:00 ksh
xxxxx    32424 11703  0 13:42 pts/1    00:00:00 ksh
xxxxx    32429 32424  0 13:43 pts/1    00:00:00 grep bad
xxxxx    32430 32429  0 13:43 pts/1    00:00:00 /bin/sleep 60
xxxxx    32431 32424  0 13:43 pts/1    00:00:00 ps -f
$

The grep process wound up as parent and the sleep process wound up as child. I would not want to bet that it always works that way. And no I don't have a special grep process that knew to establish the child.
I stand corrected on my statement that grep and ls will be siblings. They usually are, but its an unprescribed implementation detail. I think my analysis is generally sound, though.

For kicks, I tested your sleep-grep pipeline on a few shells (old versions on a disused laptop); for each shell, I ran the pipeline in the background and in the foreground. att ksh93 backgrounded was the only one of six scenarios which showed that parent-child child relationship.

att ksh93: bg: parent-child
att ksh93: fg: siblings
bash: bg: siblings
bash: fg: siblings
pdksh: bg: siblings
pdksh: fg: siblings

Regards,
Alister
This User Gave Thanks to alister For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

about different redirection

explain the redirections 1>, 2>, 3>, ..... and 1< ,2<,3<..... where we use these things thanks Thread moved from AIX forum (2 Replies)
Discussion started by: tsurendra
2 Replies

2. Solaris

solaris redirection

Hi I am using solaris 10. When running a grep command with multiple files the output is the same as the order of the input. As soon as I pipe the output to another command then it seems that standard error takes precedence, over standard output and gets sent to the pipe first. ie grep -c... (7 Replies)
Discussion started by: chronics
7 Replies

3. Shell Programming and Scripting

Redirection

Hello All, I am using the below script to gather various tools running by the user, we have more than 100 tools running on the server so my challenge is to redirect memory & cpu load to the file with the name of the tool.so am using the below script i am stucking how to redirect to the file... (2 Replies)
Discussion started by: ajaincv
2 Replies

4. Shell Programming and Scripting

Redirection question

I want to redirect stderr and have the following peice of code $ cat t1.ksh #!/bin/ksh func2() { diff /tmp/jdlkwjdlkejew /tmp/djlkwejdlewdjew >$OUTPUT_FILE 2>>$ERR_FILE } func1() { let counter=0 while do print -u2 "Error: In main function" func2 let... (1 Reply)
Discussion started by: BeefStu
1 Replies

5. Web Development

Apache redirection

Hello I have a domain where i need a redirection as described below : i.e mydomain.com/t-ABC-048796/sample.jpg must redirect to mydomain.com/jjj/top/8796/sample.jpg As you can see from the source URL (mydomain.com/t-ABC-048796/sample.jpg) i need the last four characters... (2 Replies)
Discussion started by: unimaxlin
2 Replies

6. UNIX for Dummies Questions & Answers

Help with Redirection

Hi Guys, I m new to UNIX and new to this forum. Was wondering if someone can help me understand redirection (standard input output pipeline etc) for starters, not too sure what this would mean who | sort > sortedfile | pr | lp im starting to understand common commands but when throwing... (2 Replies)
Discussion started by: jmack123
2 Replies

7. Shell Programming and Scripting

Perl Redirection

Hi, I have a Perl script that finds some files based on some criteria and then it processes the file contents using some logic. Extract: print "Started ... "; my $command = "<unix command>"; @arr=`$command`; $size=@arr; print "Size: ".$size If I turn on the Perl debugging option then I... (3 Replies)
Discussion started by: King Nothing
3 Replies

8. Shell Programming and Scripting

redirection problem

hi all, how to redirect the stdout msg in command line and file at the same time? e.g i got the script named test.sh, content as following: #!/bin/sh echo "111" when i run the script ./test.sh > log.log, it will wirte the "111" into log.log, but how to show the "111" in command line... (2 Replies)
Discussion started by: eric_wong_ch
2 Replies

9. Shell Programming and Scripting

redirection

Hi, The code below works, it's a part of a bash shell script that serve to search a pattern $pattern_da_cercare in the files contained in a directory $directory_iniziale. Now the proble is: How can I redirect stderr to a file? PS: so I want to redirect ALL the errors to a file. I tryed... (9 Replies)
Discussion started by: DNAx86
9 Replies

10. Programming

Help with redirection

Here is my problem. I don't know make this redirection thing work. The output file (called output.c) looks like this #include<stdio.h> int main() { int k; int m; print f("%d\n", k); printf("%d\n", m); return 0; } the input file(called input.c) is this #include<stdio.h> int... (2 Replies)
Discussion started by: Shallon1
2 Replies
Login or Register to Ask a Question