I can read from /dev/null; how to fix it?
I read the Wikipedia article on /dev/null
and was playing around by moving files to /dev/null
.
For this I created a test_file
and put some contents in it:
$ touch test_file
$ echo "This is written by Aditya" > test_file
$ cat test_file
This is written by Aditya
Thereafter I tried to move the file to /dev/null
:
$ mv test_file /dev/null
mv: inter-device move failed: ‘test_file’ to ‘/dev/null’; unable to remove target: Permission denied
Since, this gave me a Permission denied
Error; I went ahead and used sudo
as I normally do whenever I encounter a Permission denied
error.
$ sudo mv test_file /dev/null
The command succeeded and test_file
is no longer present in the directory.
However, the Wikipedia article says that it is not possible to recover anything moved to /dev/null
and it gives an EOF
to any process that tries to read from it. But, I can read from /dev/null
:
$ cat /dev/null
This is written by Aditya
What did I do wrong and how do I fix /dev/null
back to normal? And why did I encounter Permission denied
error in the first place?
/dev/null
is a file. A special file. A device file like /dev/sda or /dev/tty that talks to a piece of hardware on your system.
The only difference with /dev/null
is that no hardware is linked to it. Any data you send to it is silently discarded. Like the following command:
echo "Hello World" > /dev/null
which won't print anything on your terminal because you send the output of echo
to null, to the void, a black hole thus.
But when you did mv test_file /dev/null
you've replaced the special file /dev/null
by a normal text file, holding a copy of the content of your test_file
.
In other words, you've lost your /dev/null
.
Now, what you have to do is (to reconstruct it):
sudo rm /dev/null
sudo mknod -m 0666 /dev/null c 1 3
You should reconstruct it because a lot of scripts by default send output to /dev/null
. If /dev/null
is no more a black hole but a regular text file, it may grow, grow and fill your file-system up. And I'm sure you want to avoid this.
And much more dangerous, a lot of scripts assume that reading from /dev/null
will read nothing; breaking this assumption can lead to random garbage written in files all around your system... practically impossible to fix up.
And remember that Linux is multi-tasking: while you are playing with /dev/null
, a lot of processes are running and can wreak havoc even during a few seconds "window of opportunity".
If you want to play with /dev/null
you can create a copy and experiment with it:
sudo mknod -m 0666 /tmp/null c 1 3
Will create a /tmp/null
file that works in the exactly same way of /dev/null
but that you can manipulate and test without any risk for your system.
There is a big difference between overwriting a file and writing to a file.
When you write something to /dev/null
, e.g.,
$ echo Hello > /dev/null
...it gets silently discarded. For this you need write permissions to /dev/null
, which everyone has:
$ ls -l /dev/null
crw-rw-rw- 1 root root 1, 3 Mar 18 13:17 /dev/null
When you overwrite /dev/null
, as you did with the mv
command, you replace the special file /dev/null
with whatever you moved there. Don't do this! The reason you needed root privileges to do that is because to overwrite a file, you need write permissions to the directory that contains the file, in this case /dev
:
$ ls -ld /dev
drwxr-xr-x 16 root root 4640 Mar 18 13:17 /dev
To restore /dev/null
, issue the commands
$ sudo rm /dev/null
$ sudo mknod -m 0666 /dev/null c 1 3
(Also see U&L StackExchange: How to create /dev/null
)
When you run the command
$ sudo mv test_file /dev/null
you have replaced the special file /dev/null
with your text file. Subsequent attempts to read from /dev/null
return the contents of your text file, and programs that attempt to use /dev/null
in the normal way will probably break.
Replacing or deleting device files in /dev/
requires superuser privileges, which is why your non-sudo attempt failed with an error.
See Benoit's answer for information on how to restore /dev/null
manually, but since most (if not all) of the content of /dev/
is managed dynamically by udev, I suspect a simple reboot will probably fix it too.
To answer your question of what you should have done, to remove a file, you do:
rm test_file
As others have stated, /dev/null is a destination for the output of programs.