Novell Cool Solutions: Feature
By Manoj Gupta
Digg This -
Posted: 30 Oct 2007
Technically /dev/null is defined as a null device. Anything written to it is lost forever. If you read the wiki description of /dev/null, you will get to know lots of jargons/metaphors written/referred by UNIX techies a lot. In this article, we will concentrate on the importance of /dev/null, why it is there, and how to use it.
When things written to it are lost forever, then why do we need it? This is a valid questions, but we need /dev/null/ to lose information. That's correct, to explain let's take an example:
Suppose, you want to list all files of directory /var/tmp/ having word "foo" in its content. To achieve the task, we will write something as:
]$ grep -l foo /var/tmp/* /var/tmp/storagedata /var/tmp/storagedata.0 grep: /var/tmp/td.log: Permission denied
So we got two files having word "foo"; but we also an annoying error message which was part of STDERR. We were not interested in any error message, and we wanted to see only those files which I am permitted to read. So, how do I get rid of this error message? Luckily newer version of grep provides a silent option "-s", using which we can get rid of this message. But what if I am working on a traditional system, having traditional grep? What if the system command is not having the silent option? The solution is given below:
Capturing STDOUT only
- Using newer grep:
]$ grep -ls foo /var/tmp/* /var/tmp/storagedata /var/tmp/storagedata.0
- Using traditional grep:
]$ grep -l foo /var/tmp/* 2>/dev/null /var/tmp/storagedata /var/tmp/storagedata.0
- In general using any system command :
]$ cmd 2>/dev/null
Most of you should have captured the importance of /dev/null by now. In simple words, by using "2>/dev/null", we are asking the shell to redirect the STDERR to /dev/null. This is very useful when we execute system command through a program and expect to get only the STDOUT.
There may also be a case, when we are only interested to see the error message (STDERR), and are not at all interested in STDOUT. To get STDERR, and to discard the STDOUT we will redirect the STDERR to STDOUT and will redirect the STDOUT to /dev/null; as given below:
Capturing STDERR only
]$ cmd 2>&1 1>/dev/null
You may be thinking, that if I am redirecting STDERR to STDOUT which in-turn is redirected to /dev/null, so there should not be any output. But that is not the case, and you get the error messages.
Let's take another example, in which we have a list of administrators (admin.txt), a list of developers (develop.txt), and a list of people nominated for promotion (nominated.txt). The content of each of these files are emailIDs, each on a separate line example:
Now, let's play with each of above files, and try to learn few more things, not just /dev/null.
- Developers nominated for promotion (Intersection):
]$ for i in `cat develop.txt `; do grep $i nominated.txt >/dev/null && echo $i ; done email@example.com firstname.lastname@example.org
- Developers not nominated for promotion (Negation of above):
]$ for i in `cat develop.txt `; do grep $i nominated.txt >/dev/null || echo $i ; done email@example.com firstname.lastname@example.org email@example.com firstname.lastname@example.org
- People who missed the nomination:
]$ for i in `cat develop.txt ` `cat admin.txt `; do grep $i nominated.txt >/dev/null || echo $i ; done email@example.com firstname.lastname@example.org email@example.com firstname.lastname@example.org email@example.com firstname.lastname@example.org
In each of the above case, we can see that, we are not interested in grep's output, but are only interested in the return/exit value of the command grep. If grep exits with any positive value, that means the word is present, else not, and this becomes a decision point.
So far, we have learnt to take advantage of /dev/null in shell scripts. Now, let's do something more. Suppose there's a process which runs as daemon and does lots of unnecessary logging (/var/tmp/foo.log). The logging done by the daemon is really huge, and by end of week, it becomes so large that system starts running out of free space, there by alarming the administrator, who wakes up and takes appropriate action. If the log is of least importance with zero business impact, administrator usually cleans the files ( ]$ echo > /var/tmp/foo.log ). So, by end of every week, the administrator ensures that he cleans the logs, else he will be alarmed in the weekends. We can avoid this, if we symlink the log file /var/tmp/foo.log to /dev/null. Linking the log file /var/tmp/foo.log to /dev/null and writing to /var/tmp/foo.log, means writing to /dev/null, means discarding information. So, even if the daemon is logging information in /var/tmp/foo.log, the information is never saved and is lost forever.
Advantage of /dev/null can also be seen in email system. In Sendmail, the email ID "nobody" is actually pointing to /dev/null. Taking a hint from this, let's say we want to discard all incoming mails of an employee (email@example.com) , who is no more with the organization (ABC Ltd). In this case, we can point the email ID foo to /dev/null in the aliases file of sendmail. Below is the snap of aliases file of sendmail, having foo pointing to /dev/null.
nobody : /dev/null foo : /dev/null
Remember that we are discarding all the mails for foo, that means there will be no intimation to the sender, and the sender will believe that the mail was delivered.
Opening handle to /dev/null/ through a Perl program:
#!/usr/bin/perl open( HELL , ">/dev/null" ) ; print HELL "Dumping to hell \n"; close (HELL);
We may be thinking of reasons for opening handle to /dev/null, but read next. Suppose, there's a package routine which takes a HANDLE (could be FILE) as an argument, and returns some value after processing into the handle. There may be a situation, in which developer may not be interested in the things saved/written into the FILE handle and he only needs the return value of the routine. In this case, he can open a handle to /dev/null and can pass that handle to the routine, and can get the return value.
In Perl, there is a concept of linking file handles. Example: *FILE = *HELL; which means, now anything written to FILE will get written to HELL. We can use this feature/logic/hack for debugging Perl code under development.
Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com