31

When trying to move a test_dir directory to /dev/null, I get the message

mv: cannot overwrite non-directory ‘/dev/null’ with directory ‘test_dir/’

Then why do people say "Don't run the command sudo mv ~ /dev/null, it will move your home directory to a hole?"

Link

But /home is also a directory.

Braiam
  • 69,112
Avinash Raj
  • 80,446

4 Answers4

43

Because people assume. I was one of those people until I tested it. It's easy to understand why people assume... It looks dangerous...

... but you can't actually move things to /dev/null — It's a special file that just absorbs redirects (and sends them into nothingness). If you try to move a directory to it, the filesystem will verbosely explode in your face and if you try to move a file to it, you will probably end up replacing it.

The first link will deal with directories, but here's a separate test just for overwriting it with a file. As Rmano points out in the comments, this is probably something you shouldn't do without adult supervision. There is risk involved.

$ echo "this is my file" > test
$ cat test
this is my file

$ sudo mv test /dev/null
$ cat /dev/null
this is my file

# Fix this!
$ sudo rm /dev/null
$ sudo mknod -m 0666 /dev/null c 1 3
Oli
  • 299,380
19

/dev/null is just a file, it's a "special character" file but it's non the less still bound by the rules that files must follow. That being said you could never run this command:

$ mv ~ /dev/null

The mv command won't allow this since you're moving a directory to a file, that just doesn't make sense contextually and mv knows this.

Example

$ mkdir dir
$ touch afile
$ mv dir afile
mv: cannot overwrite non-directory ‘afile’ with directory ‘dir’

You can't copy onto /dev/null either, given it's a character file, if you try to copy a regular file onto it.

$ cp ~/bzip2_1.0.6-4_amd64.deb /dev/null
$ ls -l |grep null
crw-rw-rw-  1 root root        1,   3 Mar 16 14:25 null

About the only thing you can do to this file is copy mv over it another file or delete it.

$ mv /path/to/afile /dev/null

After this command, /dev/null is a regular file. The most dangerous effect of this change is that /dev/null is supposed to never output any data, so a number of shell script will assume that

`... < /dev/null` 

is equivalent to say "nothing". Having this assumption broken can lead to random data (well, the data the last process wrote to `/dev/null') inserted in system files all around the system --- which could lead to an utterly broken and unrecoverable system.

Rmano
  • 32,167
slm
  • 3,155
13

You can write files or other input streams to /dev/null but not directories. If you try moving a directory to /dev/null it would report an error since /dev/null is not a directory but a file.

However, since you want to experiment with /dev/null, you are first suggested to know the consequences to moving a file to overwrite /dev/null and how to recover from that situation:

As suggested by @Rmano in this answer to that question, in order to experiment with /dev/null we should rather create a copy of it and then do our experimentation. So, let's create /tmp/null and use it for our experimentation purposes:

sudo mknod -m 0666 /tmp/null c 1 3

Now onwards, /tmp/null is our /dev/null for all purposes:

Let us create a test_file and a test_dir inside a directory called ask_ubuntu.

$ mkdir ask_ubuntu
$ cd ask_ubuntu
$ touch test_file
$ mkdir test_dir
$ echo "Let us test if we can recover our test_file." > test_file

The following shows the contents of ask_ubuntu directory:

$ ls -la
total 12
drwxr-xr-x 3 aditya aditya 4096 Mar 18 17:10 .
drwxr-xr-x 4 aditya aditya 4096 Mar 18 17:10 ..
drwxr-xr-x 2 aditya aditya 4096 Mar 18 17:10 test_dir
-rw-r--r-- 1 aditya aditya    0 Mar 18 17:10 test_file

Now try to move our test_file to /tmp/null and see the contents of ask_ubuntu:

$ sudo mv test_file /tmp/null   # This succeeds
$ ls -la
total 12
drwxr-xr-x 3 aditya aditya 4096 Mar 18 17:12 .
drwxr-xr-x 4 aditya aditya 4096 Mar 18 17:10 ..
drwxr-xr-x 2 aditya aditya 4096 Mar 18 17:10 test_dir

The command succeeds and test_file is no longer available. Now try to move test_dir to /tmp/null which doesn't succeed:

$ sudo mv test_dir/ /tmp/null 
mv: cannot overwrite non-directory ‘/tmp/null’ with directory ‘test_dir/’

test_dir is still present inside ask_ubuntu:

$ ls -la
total 12
drwxr-xr-x 3 aditya aditya 4096 Mar 18 17:12 .
drwxr-xr-x 4 aditya aditya 4096 Mar 18 17:10 ..
drwxr-xr-x 2 aditya aditya 4096 Mar 18 17:10 test_dir

Now, let us figure if we can recover our test_file from /tmp/null:

$ cat /tmp/null
Let us test if we can recover our test_file.

So, it is still there and /tmp/null which was a special file has been overwritten and it has become like any other normal file. We can recover our file by copying /tmp/null just like any other file:

$ cp /tmp/null our_test_file
$ cat our_test_file
Let us test if we can recover our test_file.

File recovered.

Note:

If you didn't create /tmp/null and tried those commands directly using /dev/null; make sure you recover the file (if you need to) by running cp /dev/null our_test_file; and restore /dev/null for the purposes it exists on our system by running the following commands as given in the linked question as soon as possible:

$ sudo rm /dev/null
$ sudo mknod /dev/null c 1 3
$ sudo chmod 666 /dev/null

Conclusion:

  • So, it is impossible to move a directory to /dev/null and hence there is no question of recovering the directory from there.

  • As far as files are concerned, if you directly move files to /dev/null, you can still recover it as demonstrated above. However, there are two exceptions:

    1. During the period you run sudo mv test_file /dev/null and cp /dev/null our_test_file, if any root script in the system overwrites it by running echo "Whatever text the root script wants to send to /dev/null" > /dev/null (or other similar commands). Then we do not have any easy way to recover our file.

    2. If you reboot the system between running those two commands. /dev/null gets re-created at boot, so our file gets lost when we shut down the computer.

  • But if you want to recover input streams like echo "Stream this line to /dev/null" > /dev/null, you cannot recover that since /dev/null is a special file to dispose off unwanted files and input streams and as the Wikipedia article mentions, it doesn't provide any data to a process that reads from it.


Reference: Wikipedia Article on /dev/null

Aditya
  • 13,616
7

Everything sent to /dev/null is silently discarded. If you type:

echo "Hello World"

you get Hello World on the screen. If you type:

echo "Hello World" >/dev/null

you don't get anything on the screen.

But in the case of the move command, the command mv try to replace the file /dev/null by the directory, what is not possible. Because everything is a file in Linux, /dev/null is a file. A special one of course (a device file), a special file allowing accessing piece of hardware (like disks, partitions, sound cards, serial ports, ...). In the case of /dev/null, this is not linked to any piece of hardware so the data sent to it is silently discarded. This is why "they" may have called it a blackhole.

muru
  • 207,228
Benoit
  • 7,637