You've probably heard of stdout (standard out) and stdin (standard in) before but may not know what they really mean. Basically, when you run a program in the shell like 'ls' or 'grep' the output that it produces is sent to stdout, which is your terminal window. stdin is basically the opposite, instead of getting data from a file, stdin is opened up to a pipe for input to the program. If you have ever put '| less' after a command to control the amount of output you get at once, you've used stdin. By using the pipe symbol (|) you are redirecting the stdout from a program like 'ls' to the stdin of 'less'.
[user@host ~]$ ls -l | less total 53 drwxr-xr-x 2 suso suso 1024 Dec 7 19:10 ./ drwxr-xr-x 3 suso suso 1024 Nov 27 06:32 ../ -rw------- 1 suso suso 12288 Dec 7 19:21 .ioredirect.phtml.swp -rw-r--r-- 1 suso suso 3763 Dec 6 03:44 bangcharacter.phtml -rw-r--r-- 1 suso suso 1574 Dec 7 03:29 electricfence-readme -rw-r--r-- 1 suso suso 127 Nov 27 06:56 footer.phtml -rw-r--r-- 1 suso suso 219 Dec 6 00:58 header.phtml -rw-r--r-- 1 suso suso 1496 Dec 7 03:51 index.phtml -rw-r--r-- 1 suso suso 3132 Dec 7 19:10 ioredirect.phtml -rw-r--r-- 1 suso suso 3132 Dec 7 02:49 jobcontrol.phtml -rw-r--r-- 1 suso suso 5231 Dec 6 03:33 movement.phtml -rw-r--r-- 1 suso suso 6842 Dec 7 19:09 regularexpressions.phtml -rw-r--r-- 1 suso suso 3132 Dec 7 02:55 regularexpressions.phtml~ -rw-r--r-- 1 suso suso 3680 Dec 5 20:00 shellvariables.phtml (END)
The output of ls is treated just like it was a file and you had typed less
Another way you can redirect stdout is by using the angle operators, <>. If you want to send stdout to a file you use '> filename'. If you want to send the contents of a file to the stdin of a program, you can do '<>
[user@host ~]$ ls -l > listoutput [user@host ~]$ cat listoutput total 53 drwxr-xr-x 2 suso suso 1024 Dec 7 19:10 ./ drwxr-xr-x 3 suso suso 1024 Nov 27 06:32 ../ -rw------- 1 suso suso 12288 Dec 7 19:21 .ioredirect.phtml.swp -rw-r--r-- 1 suso suso 3763 Dec 6 03:44 bangcharacter.phtml -rw-r--r-- 1 suso suso 1574 Dec 7 03:29 electricfence-readme -rw-r--r-- 1 suso suso 127 Nov 27 06:56 footer.phtml -rw-r--r-- 1 suso suso 219 Dec 6 00:58 header.phtml -rw-r--r-- 1 suso suso 1496 Dec 7 03:51 index.phtml -rw-r--r-- 1 suso suso 3132 Dec 7 19:10 ioredirect.phtml -rw-r--r-- 1 suso suso 3132 Dec 7 02:49 jobcontrol.phtml -rw-r--r-- 1 suso suso 5231 Dec 6 03:33 movement.phtml -rw-r--r-- 1 suso suso 6842 Dec 7 19:09 regularexpressions.phtml -rw-r--r-- 1 suso suso 3132 Dec 7 02:55 regularexpressions.phtml~ -rw-r--r-- 1 suso suso 3680 Dec 5 20:00 shellvariables.phtml [user@host ~]$
[root@host /usr/src/linux]# patch -p1 <>You can also append the output of a program to a file using double greater-than signs (>>).
[root@host ~]# tail /var/log/messages Dec 7 18:22:51 host ftpd[26820]: FTP session closed Dec 7 18:22:52 host ftpd[26821]: ACCESS DENIED (not in any class) TO dhcp-33.domain.net [xxx.xxx.xxx.xxx] Dec 7 18:22:52 host ftpd[26821]: FTP LOGIN REFUSED (access denied) FROM dhcp-33.domain.net [xxx.xxx.xxx.xxx], xxxxxxxx Dec 7 18:22:52 host ftpd[26821]: FTP session closed Dec 7 18:23:04 host ftpd[26825]: FTP LOGIN FROM dhcp-33.domain.net [xxx.xxx.xxx.xxx], xxxxxxxx Dec 7 18:23:06 host ftpd[26827]: FTP LOGIN FROM dhcp-33.domain.net [xxx.xxx.xxx.xxx], xxxxxxxx Dec 7 18:26:29 host ftpd[26827]: FTP session closed Dec 7 19:00:59 host PAM_pwdb[27479]: (su) session opened for user news by (uid=0) Dec 7 19:01:01 host PAM_pwdb[27479]: (su) session closed for user news Dec 7 19:59:48 host PAM_pwdb[28448]: (su) session opened for user root by suso(uid=500) [root@host /root]# echo "Dec 7 20:00:30 host messaged: Hi Mom." >> /var/log/messages [root@host /root]# tail /var/log/messages Dec 7 18:22:52 host ftpd[26821]: FTP session closed Dec 7 18:23:04 host ftpd[26825]: FTP LOGIN FROM dhcp-33.domain.net [xxx.xxx.xxx.xxx], xxxxxxxx Dec 7 18:23:06 host ftpd[26827]: FTP LOGIN FROM dhcp-33.domain.net [xxx.xxx.xxx.xxx], xxxxxxxx Dec 7 18:26:29 host ftpd[26827]: FTP session closed Dec 7 19:00:59 host PAM_pwdb[27479]: (su) session opened for user news by (uid=0) Dec 7 19:01:01 host PAM_pwdb[27479]: (su) session closed for user news Dec 7 19:59:48 host PAM_pwdb[28448]: (su) session opened for user root by suso(uid=500) Dec 7 20:01:00 host PAM_pwdb[28639]: (su) session opened for user news by (uid=0) Dec 7 20:01:01 host PAM_pwdb[28639]: (su) session closed for user news Dec 7 20:00:30 host messaged[]: Hi Mom. [root@host /root]#There is also stderr which with is like stdout, but is the erroneous output that comes out of a program. Sometimes you might be redirecting the output of a program and you will still see output in your terminal window, this is stderr output.
[root@host /root]# ls -l /var/log /var/log/httpd/access_og > logslist ls: /var/log/httpd/access_og: No such file or directory [root@host /root]#That line of output that says that the file access_og doesn't exist was sent by the ls program to stderr, which the > doesn't catch. If you want to catch the output of stderr you have to use the n> notation to express which output filehandle number you wish to use. In the case of stderr, that number is 2.
[root@host /root]# ls -l /var/log /var/log/httpd/access_og 2> logslist -rw------- 1 root root 1463915 Dec 7 20:22 cron -rw-r--r-- 1 root root 2574 Jan 30 2000 dmesg -rw-r--r-- 1 root root 0 May 6 1999 htmlaccess.log drwxr-xr-x 2 root root 17408 Dec 1 00:04 httpd/ -rw-r--r-- 1 root root 157972 Dec 7 15:10 lastlog -rw------- 1 root root 688206 Nov 30 23:40 maillog -rw------- 1 root root 365531 Dec 7 20:11 messages -rw-r--r-- 1 root root 0 Dec 1 00:04 netconf.log -rw------- 1 root root 561272 Dec 7 20:19 secure -rw-r--r-- 1 root root 162275 Dec 7 04:23 spinwebd -rw------- 1 root root 337 Dec 7 00:04 spooler -rw-rw-r-- 1 root utmp 92544 Dec 7 18:26 wtmp -rw------- 1 root root 0 Dec 1 00:04 xferlog [root@host /root]# cat logslist ls: /var/log/httpd/access_og: No such file or directory [root@host /root]#To get both the stdout and stderr to go to a file we use a combination of > and 2>&1, which means that we want to duplicate the output of file descriptor 1 and put it on file descriptor 2. So both stdout (1) and stderr(2) get sent to the file 'logslist'.
$
cat food
2>&1>
file
cat: can't open food $cat food
file
2>
&
1 $
Although lots of sh manual pages don't mention this, the shell reads arguments from left to right.
On the first command line, the shell sees
2>&1
first. That means "make the standard error (file descriptor 2) go to the same place as the standard output (fd1) is going." There's no effect because both fd2 and fd1 are already going to the terminal. Then>file
redirects fd1 (stdout) tofile
. But fd2 (stderr) is still going to the terminal.On the second command line, the shell sees
>file
first and redirects stdout tofile
. Next2>&1
sends fd2 (stderr) to the same place fd1 is going - that's to the file. And that's what you want.
No comments:
Post a Comment