What does /dev/null mean in a shell script?
Solution 1
cat
will list the contents of a file comming after cat
to standard output and the >
sends it to the file messages
and wtmp
where > means to first remove all contents of the file and >> would mean to ADD to the current file. In this case you are using > so the file will end up being empty.
Now for the kicker: /dev/null
is a device that sends 'nothing' to the 2 files behind the >.
There is a reason to do it like this: the file is NOT removed from the system. If you would rm
it and then do a touch messages
the permissions might be wrong and if just after the rm
something would want to write to the file it would be gone and error out. Depending on how the software is created it could crash.
Solution 2
Assuming the commands succeeded, /var/log/messages
and /var/log/wtmp
still exist but are now blank.
Shell Redirection
>
is a redirection operator, implemented by the shell. Its syntax is:
command > file
This redirects command
's standard output to file
.
-
file
may also be a device node. - If
file
doesn't exist, it is created as a regular file. - If
file
already exists as a regular file and is non-empty, it is overwritten. This is typically the case in the commands you ran, where you redirected the output ofcat /dev/null
tomessages
andwtmp
. - If
file
already exists as a symbolic link, the link's target is used. - If
file
already exists as a directory, you'll get an error likebash: file: Is a directory
.
(Of course, these operations may fail for other reasons, such as lack of permissions or a filesystem error.)
The >>
redirection operator is similar, but it appends to the end of non-empty regular files instead of overwriting their contents. (Another redirection operator is <
. command < file
uses file
as command
's standard input.)
The null
Device
/dev/null
is a simple device (implemented in software and not corresponding to any hardware device on the system).
-
/dev/null
looks empty when you read from it. - Writing to
/dev/null
does nothing: data written to this device simply "disappear."
Often a command's standard output is silenced by redirecting it to /dev/null
, and this is perhaps the null
device's commonest use in shell scripting:
command > /dev/null
You're using /dev/null
differently. cat /dev/null
outputs the "contents" of /dev/null
, which is to say its output is blank. > messages
(or > wtmp
) causes this blank output to be redirected to the file on the right side of the >
operator.
Since messages
and wtmp
are regular files (rather than, for example, device nodes), they are turned into blank files (i.e., emptied).
You could use any command that does nothing and produces no output, to the left of >
.
An alternative way to clear these files would be to run:
echo -n > messages
echo -n > wtmp
The -n
flag is required, or echo
writes a newline character.
(This always works in bash
. And I believe the default sh
in every GNU/Linux distribution and other Unix-like system popularly used today supports the -n
flag in its echo
builtin. But jlliagre is right that echo -n
should be avoided for a truly portable shell script, as it's not required to work. Maybe that's why the guide you're using teaches the cat /dev/null
way instead.)
The echo -n
way is equivalent in its effects but arguably is a better solution, in that it's simpler.
cat /dev/null > file
opens three "files":
- The
cat
executable (usually/bin/cat
), a regular file. - The
/dev/null
device. file
In contrast, echo -n > file
opens only file
(echo
is a shell builtin).
Although this should be expected to improve performance, that's not the benefit--not when just running a couple of these commands by hand, anyway. Instead, the benefit is that it's easier to understand what's going on.
Redirection and the trivial (blank/empty) command.
As jlliagre has pointed out (see also jlliagre's answer), this can be shortened further by simply omitting the command on the left of >
altogether. While you cannot omit the right side of a >
or >>
expression, the blank command is valid (it's the command you're running when you just press Enter on an empty prompt), and in omitting the left side you're just redirecting the output of that command.
- Note that this output does not contain a newline. When you press Enter on a command prompt--whether or not you've typed anything--the shell (running interactively) prints a newline before running the command issued. This newline is not part of the command's output.
Redirecting from the blank command (instead of from cat /dev/null
or echo -n
) looks like:
> messages
> wtmp
Solution 3
As already answered, these two lines are clearing the content of the /var/log/messages
and /var/log/wtmp
files, or are creating them in the unlikely event they do not already exist.
However, they are based on a well established urban legend that gives /dev/null
"paranormal" powers.
It actually has none so cat /dev/null
is a waste of keystrokes, time and CPU cycles as it outputs absolutely nothing. Eliah Kagan's reply suggests the better approach which is using echo -n
instead. This is better but not portable to some shells/OSes where it might put the '-n
' string into these files.
You can go further and replace these commands by the portable and simpler:
cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
With most shells (but not the csh
based ones), you can go even further and remove the no-op command ':
' :
cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
Solution 4
>
is output redirecting operator. It will redirect the output of command to file mentioned after it instead of standard output device, truncating or overwriting file's contents.
for example ls -l > demo.txt
. After executing this command, "demo.txt"
will contain th output ls -l
command.
Now next thing is what is this /dev/null
./dev/null
is the null file Is is a special file which contains nothing.
So when you execute commands
cat /dev/null > messages
cat /dev/null > wtmp
it clears the contents of "messages" and "wtmp" file by overwriting with EOF(End Of File) character.
So here you are not clearing your /var/log
directory, but you are clearing the contents of these two files.
Solution 5
/dev/null is like a black hole. Writes made to the /dev/null are discarded. In this script, they are using /dev/null to empty the message log file.
Otherwise they could have simply used.
> /var/log/messages.
There are other ways to empty the contents of a file.
Like.
truncate -s 0 /var/log/messages
cp /dev/null /var/log/messages
But using ">" or "/dev/null" is the efficient way.
Related videos on Youtube
![rishiag](https://i.stack.imgur.com/npj3F.jpg?s=256&g=1)
Comments
-
rishiag almost 2 years
I've started learning bash scripting by using this guide: http://www.tldp.org/LDP/abs/abs-guide.pdf
However I got stuck at the first script:
cd /var/log cat /dev/null > messages cat /dev/null > wtmp echo "Log files cleaned up."
What do lines 2 and 3 do in Ubuntu (I understand
cat
)? Is it only for other Linux distributions? After running this script as root, the output I get isLog files cleaned up.
But/var/log
still contains all the files. -
Mr. Llama almost 10 years
cat "echo" > messages
will give you a blank file, but also the messagecat: echo: No such file or directory
.cat
will relay anything on STDIN, but it doesn't print parameters likeecho
does. I would personally recommendecho "" > file
as the intent is clear and unambiguous. -
jlliagre almost 10 years
echo "" > wtmp
will create an unusablewtmp
file (as non empty) and then prevent programs that use it to work. -
jlliagre almost 10 yearsYou can go further and replace the useless
echo -n
by:
or just nothing, given the fact the command does nothing anyway. -
Boris the Spider almost 10 years@Mr.Llama I would recommend that
truncate
for this - why use an echo and a pipe when there is a command explicitly designed for this task. -
Boris the Spider almost 10 yearsRather than
echo -n
I would recommend you usetruncate
- using a command designed for the purpose is, in my option, a little clearer to future readers of the script. -
jlliagre almost 10 years@BoristheSpider I get your point about readability but the shell can do it a simpler way with an empty redirection.
-
Eliah Kagan almost 10 years@jlliagre You're right: while I thought to suggest
echo -n > messages
as it's self-documenting, it's arguably even better and more instructive to use> messages
, which is equivalent. Thank you for pointing this out--I've expanded my answer to cover this option. (: > messages
is fine too, though personally I don't particularly care for it--it has the same meaning astrue > messages
,true
also being a shell builtin. If I'm going to to redirect from a named command,echo -n
is self-documenting as to its purpose lying in its output.) -
Eliah Kagan almost 10 yearsI see the benefit of redirecting from
:
(rather than from nothing) in that it will work with non-Bourne-style shells, such as csh/tcsh. Are there also Bourne-style shells that won't redirect stdout from an empty command? -
jlliagre almost 10 years@BoristheSpider Why use a explicitly designed command when no command at all do the same job ? ;-)
-
Boris the Spider almost 10 years@jlliagre Ha! Although I would hate to see your scripts...
-
jlliagre almost 10 years@EliahKagan No Bourne style shell I'm aware of won't redirect stdout from an empty command. This was already the case with the Unix version 7 (1979) original Bourne shell.
-
MadTux almost 10 yearsWhat about
printf "" > wtmp
? -
Rinzwind almost 10 years@jlliagre answer that and you found 1 of the mysteries of coding software ;)