130 likes | 148 Views
Learn how to redirect stdin, stdout, and stderr in Unix programs efficiently. Explore pipes and named pipes for inter-process communication. Discover methods to redirect I/O streams and handle file descriptors in C programs. Enhance your skills in Unix redirection today!
E N D
Agenda • Redirection: • Purpose • Redirection Facts • How to redirecting stdin, stdout, stderr in a program • Pipes: • Using Pipes • Named Pipes
Redirection • We have learned in Unix and Linux how to redirect stdin, stdout and stderr: • < or 0< - redirect stdin to command • << or 0<< - redirect stdin within command • > or 1> - redirect stdout to file (overwrite if file not empty) • >> or 1>> - redirect stdout to file (append if file not empty) • 2> - redirect stderr to file (overwrite if file not empty) • 2>> - redirect stderr to file (append if file not empty)
Redirection • Redirection Facts: • All UNIX tools use the stdin, stdout, stderr data streams, although not all stdin is read from the user (for example, the who command automatically reads stdin from a system file called /var/adm/utmp). • All UNIX tools use file descriptors 0,1 & 2. • It is the shellnot the program or script that redirects I/O (ie. stdin / stdout / stderr). This fact is proven in the next slide.
Redirection Proof that shell not programredirects stdin, stdout, stderr Note how compiling & running this programwith arguments list the program’s arguments arglist.c #include <stdio.h> main( int ac, char *av[]) { int i; printf ("Number of args: %d, Args are:\n", ac); for (i=0; i < ac; i++) printf ("args[%d]: %s\n", i, av[i]); fprintf (stderr, "This message is sent to stderr.\n"); } $ listargs > output 2> error$ cat outputNumber of args: 1, Args are:args[0]: listargs$ cat error This message is sent to stderr.$ listargs arg1 arg2 > output 2>error$ cat outputNumber of args: 3, Args are:args[0]: listargsargs[1]: arg1args[2]: arg2
Redirection • If it is the shell, not the program that redirects stdin, stdout and stderr, how can a program perform redirection? • Shell script -> use the exec utility (see mycp in sockets directory) • C program -> Use either: • close() , open() method • open(), close(), dup(), close() method • open(), dup2(), close() method Refer to stdinredir1.c, stdinredir2.c and stdinredir3.c examples in~msaul/unx511/pipes_and_redirection directory
Redirection • How do these methods work in C programs? • Processes do not read from files, they read from file descriptors • Steps are like “hanging-up the phone to get a dial-tone”, thus close file descriptor, then redefine it. • Close / Open Method: • close(0); /* file descriptor 0 – i.e. stdin */ • open(filename, O_RDONLY); /* redefines lowest file descriptor */ • Open / Close / Dup / Close / Method: • fd=open(filename, O_RDONLY) /* open file to read - fd */ • close(0); /* close file descriptor 0 – i.e. stdin */ • newfd=dup(fd); /* make “clone” of fd and kernel uses lowestnext available fd – I.e. 0 that was closed */ • close(fd); /* close original fd associated with file. Now, stdin is associated with file… */ dup2 is similar to dup,but dup2 will automaticallyclose(0).eg. newfd=dup2(fd,0);(no close before dup2)
Pipes • So far, we have shown how we can attach a file to stdin, stdout & stderr. Pipes are another “feature” of UNIX to connect stdout of one process to stdin of another process. • Pipes will only work on local machines, so if you are interested in inter-process communication via TCP/IP, it is better to use Internet Sockets. Also, pipe are uni-directional (eg. required 2 pipes for inter-process communication (IPC). • Basically, you can program to join the file descriptors of two processes: • Eg. Connect fd0 of process1 with fd1 of process2
Pipes • Basically, two methods to working with pipes: • popen() – Similar to system() call where pipe() & fork() are called automatically. This method is not very efficient, and does not give a lot of control to programmer) • Programmer uses pipe(), fork() manually. Calling pipe without using fork is like creating a process to communication with yourself. Refer to examples popen3.c and pipe2.c in the ~msaul/unx511/pipes_and_redirection directory
Pipes • How does it work? • dup and dup2 functions are used to close, then open a file descriptor (returning the new file descriptor). Like before, the Kernel uses the next available pipe (i.e. set for stdin or stdout). • The process doesn’t need to know it is communicating with a pipe. • Any standard Unix utility (used for a filter) can be used. • Notice how each process closes the file descriptors that it won’t be using… Refer to examples pipe5.c, pipe5b.c & pipe5c.c in the~/msaul/unx511/pipes_and_redirection directory
Pipes:C programming Example Visual example of mypipe.c (using pipe and fork system calls). Example contained in the ~msaul/unx511/pipes_and_redirection directory… ---------- Process #1 ---------- / | \ Process #2 Process #3 Process #4 / | \ od head wc stdin < filename stdin < pipe[0] stdin < pipe2[0] stdout > pipe[1] stdout > pipe2[1] Remember: when duplicating a process using the “fork()” system call, the child process inherits everything from the parent (including pipe file descriptors)
Named Pipes • The problem with pipe examples in previous examples involve sharing stdout / stdin among parent process and its children. • Named pipes can be used can be accessed by any local process (parent or child) – i.e. known by name. Named pipes can also be used in Shell Scripts as well as C Programs… • How named pipe is created: • In C Program: mkfifo() system call • In Shell Script: mkfifo shell command
Named Pipes:Scripting Example Time Server (time_server.bsh) #!/bin/bash# Time serverwhile truedo rm –f /tmp/time_fifo mkfifo /tmp/time_fifo date > /tmp/time_fifodone Remove Existing named pipe Create new pipe Redirect stdout to named pipe Time Client (time_client.bsh) #!/bin/bash# Time clientcat /tmp/time_fifo Read from named pipe Can setup mask while name pipe is created:eg. mkfifo –m 666 /tmp/time_fifo
Named Pipes:Client / Server Example • C Programming Example: • Can create two named-pipes that allow communication between processes. Considered simpler/easier for programming local sockets, but not useful if communicating among different servers via TCP/IP. • time_server.c * • time_client.c * • * Note that time_server.c make reference to the header file cliserv.h