Sponsored Content
Top Forums Shell Programming and Scripting Pipes with the < and >> meanings. Post 302517359 by DGPickett on Tuesday 26th of April 2011 02:32:59 PM
Old 04-26-2011
Well, the shell is a tool that opens files of various sorts and runs executables. The shell can fork() to create clones processes of itself to run subshells or execvp() programs or scripts. For the pipe between c1 and c2, the shell fork()'s a child that:
  1. opens a connected pair of pipes using pipe(),
  2. fork()'s,
  3. on the child:
    1. close()'s stdout
    2. and the output member of the pipe() array,
    3. dup()'s the input fd of the pipe() array to be stdout,
    4. close()'s the input fd of the pipe() array, and
    5. execvp()'s c1;
  4. the parent
    1. close()'s stdin
    2. and the input member of the pipe() array,
    3. dup()'s the output fd of the pipe() array to be stdin,
    4. close()'s the output fd and
    5. execvp()'s c2.
Voila, two processes running with stdout of c1 pipe()'d to stdin of c2. Of course, it has to do similar steps for the pipe on c2 to c3.

The stdin redirect < is in the wrong place, as c3 has stdin dup()'d to the pipe. The input goes into c1, and the < filename goes after that command's arguments, none in this case. It is after arguments, because, once the shell does any expansion and removes any quotes on arguments, they are the business of execvp() and the command, not the shell. For <, the shell closes stdin (originally your tty, inherited) and then open()'s the filename for read at beginning of file to be stdin.

The open() or dup() will use the lowest number fd not in use, and stdin is 0, stdout is 1. For the overly organized, paranoid and OCD, there is dup2(a,b) to dup to a specific hole in the fd array. An fd, not to be confused with a FILE*, is just an integer to reference a pointer array in the kernel space for each process. The same open file can be pointed to by many processes and many fd in each of those processes, but it is the same open file structure. Web servers even pass open socket fd's to children through a pipe with fancy calls to duplicate the parent open file structure in a child fd. The fd's that all refer to the same open file structure will all be at the same offset (bytes for beginning) for reading or writing. In shell, this means that if one command reads 3 lines and then starts another with stdin inherited, it starts reading at line 4.\

The same filename can be open()'d many times by one or more processes, and these each get new open file structures in the kernel pointing to the same device and inode. This is not the same as many fd pointing to the same open file structure. The open file structures from each open() each have a separate offset pointer for reading or writing the file.

A FILE* is a buffered fd wrapper inside a process that reads ahead or saves output to write bigger blocks. In the shell, if you 'read' a file, it uses a FILE* on stdin and reads ahead, so the next line and a good offset are not available to any inheriting process. To deal with this, you can use command 'line', which read()'s exactly one line, one byte at a time, using a fd or unbuffered FILE*. Every process starts up with three open fd: 0, 1, 2; wrapped in three open FILE* 'stdin', 'stdout', and 'stderr'; stdout is buffered for bulk output, and stderr is unbuffered for error messages that must not be in a buffer if the process crashes out with a fatal signal and perhaps a core file. Wise programmers use or reuse them first before making more fd/FILE*.

Output redirection >> and > are like < but for stdout to write to the filename, possibly creating it; > truncates any old data. More does less, a recurrent theme in shell. For instance, adding '&' means don't wait() for the child to finish. By default, to keep things simple, the shell wait()'s for all the new children to finish before reading more input. Too many & background jobs can exhaust your resources or lock up the system.

A good friend of the pipe is () the subshell. It shares/inherits one stdin, one stdout and one stderr for all commands executed inside it, concatenating output if no '&' or mixing if processes all write in rotation. Further, if there are many background processes and child processes, and you collect all their stderr using "( ... ) 2>&1 | ....", then all processes within must close stderr (exit) before the subshell finishes. This ensures you can see all error messages before proceeding, not missing any from slow, somewhat disconnected child processes.

The reverse of that is tee, which takes one stdin stream and writes a file and stdout the same. Under ksh where there is /dev/fd/# and under bash, you can put redirect to subshell in place of a file name:
Code:
 >( something you can write )
 and
 <( something that writes to you )

.

Pipes are much nicer than temp files, as you never run out of space or have name collisions where someone else owns a file under that name, plus you get 'pipeline parallelism'. For instance, this sorts two files using up to 3 CPUs:
Code:
sort -m <( sort file1 ) <( sort file2 )


Last edited by DGPickett; 04-26-2011 at 03:40 PM..
These 6 Users Gave Thanks to DGPickett For This Post:
 

10 More Discussions You Might Find Interesting

1. Filesystems, Disks and Memory

PIPEs and Named PIPEs (FIFO) Buffer size

Hello! How I can increase or decrease predefined pipe buffer size? System FreeBSD 4.9 and RedHat Linux 9.0 Thanks! (1 Reply)
Discussion started by: Jus
1 Replies

2. Shell Programming and Scripting

cd using pipes

Hi, Can the cd command be invoked using pipes??? My actual question is slightly different. I am trying to run an executable from different folders and the path of these folders are obtained dynamically from the front end. Is there a way in which i can actually run the executable... (2 Replies)
Discussion started by: Sinbad
2 Replies

3. Shell Programming and Scripting

where can I get exit code meanings?

I'm investigating strange behaviour on two boxes (Sun OS 5.10 and AIX 5.1) in ksh have used $? to get exit codes returned:- 137 and 34 where can I find what these mean? thank you (1 Reply)
Discussion started by: speedieB
1 Replies

4. Shell Programming and Scripting

named pipes

How to have a conversation between 2 processes using named pipes? (5 Replies)
Discussion started by: kanchan_agr
5 Replies

5. Cybersecurity

Syslog events meanings

Hi everybody, I'm writing to know what the following event stands for. I know that the following event is about a "su to root" action but I don't have any Idea about what action could rise this message. For example If an acction performed by the root crontab, a sudo command or something like that.... (1 Reply)
Discussion started by: PVelazco
1 Replies

6. Shell Programming and Scripting

Pipes not working

Hi, thanks for b4. can anyone tell me why following not working: noUsers=$(who | cut -d" " -f1 | wc -l) What i'm trying to do is get a list of logged on users and pass it to 'wc -l' and store the output to a variable. Any ideas? (1 Reply)
Discussion started by: Furqan_79
1 Replies

7. UNIX for Dummies Questions & Answers

learning about pipes!

im trying to figure out how to do the following: using pipes to combine grep and find commands to print all lines in files that start with the letter f in the current directory that contain the word "test" for example? again using pipes to combine grep and find command, how can I print all... (1 Reply)
Discussion started by: ez45
1 Replies

8. Shell Programming and Scripting

need meanings for FTP codes

Hi Friends, Could i get the meaning for the following FTP codes? 421 425 426 530 450 550 451 551 452 552 553 Thanks, Raja. (1 Reply)
Discussion started by: smr_rashmy
1 Replies

9. Programming

Pipes in C

Hello all, I am trying to learn more about programming Unix pipes in C. I have created a pipe that does od -bc < myfile | head Now, I am trying to create od -bc < myfile | head | wc Here is my code, and I know I might be off, thats why I am here so I can get some clarification. #include... (1 Reply)
Discussion started by: petrca
1 Replies

10. UNIX for Dummies Questions & Answers

top command: abbrevations and meanings - Please !

Hi all, I was trying see some CPU utilization of a Red hat Linux machine using 'top' command. Any way I got high level idea from the out puts, but when I observed the following line: Cpu(s): 7.4%us, 0.5%sy, 0.0%ni, 91.6%id, 0.4%wa, 0.0%hi, 0.1%si, 0.0%st I couldn't make out what... (2 Replies)
Discussion started by: a99u
2 Replies
All times are GMT -4. The time now is 09:07 AM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy