/dev/zero is an example of a “special file” — particularly, a “device node”. Normally these get created by the distro installation process, but you can totally create them yourself if you want to.
If you ask
# ls -l /dev/zero crw-rw-rw- 1 root root 1, 5 Nov 5 09:34 /dev/zero
The “c” at the start tells you that this is a “character device”; the other type is “block device” (printed by
ls as “b”). Very roughly, random-access devices like harddisks tend to be block devices, while sequential things like tape drives or your sound card tend to be character devices.
The “1, 5” part is the “major device number” and the “minor device number”.
With this information, we can use the
mknod command to make our very own device node:
# mknod foobar c 1 5
This creates a new file named
foobar, in the current folder, which does exactly the same thing as
/dev/zero. (You can of course set different permissions on it if you want.) All this “file” really contains is the three items above — device type, major number, minor number. You can use
ls to look up the codes for other devices and recreate those too. When you get bored, just use
rm to remove the device nodes you just created.
Basically the major number tells the Linux kernel which device driver to talk to, and the minor number tells the device driver which device you’re talking about. (E.g., you probably have one SATA controller, but maybe multiple harddisks plugged into it.)
If you want to invent new devices that do something new… well, you’ll need to edit the source code for the Linux kernel and compile your own custom kernel. So let’s not do that! 🙂 But you can add device files that duplicate the ones you’ve already got just fine. An automated system like udev is basically just watching for device events and calling
rm for you automatically. Nothing more magic than that.
There are still other kinds of special files:
Linux considers a directory to be a special kind of file. (Usually you can’t directly open a directory, but if you could, you’d find it’s a normal file that contains data in a special format, and tells the kernel where to find all the files in that directory.)
A symlink is a special file. (But a hard link isn’t.) You can create symlinks using the
ln -scommand. (Look up the manpage for it.)
There’s also a thing called a “named pipe” or “FIFO” (first-in, first-out queue). You can create one with
mkfifo. A FIFO is a magical file that can be opened by two programs at once — one reading, one writing. When this happens, it works like a normal shell pipe. But you can start each program separately…
A file that isn’t “special” in any way is called a “regular file”. You will occasionally see mention of this in Unix documentation. That’s what it means; a file that isn’t a device node or a symlink or whatever. Just a normal, every day file with no magical properties.
Most of the
/dev entries are block device inodes or character device inodes. Wikipedia has many detailsabout that, which I am not going to repeat.
/dev/tcp which is mentioned in your question is not explained by any of the existing answers.
/dev/udp are different from most other
/dev entries. The block and character devices are implemented by the kernel, but
/dev/udp are implemented in user mode.
The bash shell is one program which has an implementation of
/dev/udp (copied from
ksh93). When you try to open a path beneath those with bash redirection operators, it will not perform an ordinary
open system call. Instead bash will create a TCP socket and connect it to the specified port.
That is implemented in user mode and only in some programs as can be seen in the following example which demonstrates the difference between letting
cat try to open
$ cat /dev/tcp/::1/22 cat: /dev/tcp/::1/22: No such file or directory $ cat < /dev/tcp/::1/22 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.3
A difference with
ksh93 is that
bash will only do those TCP connections with redirection operators, not in the other places where it may open files like the
In addition of device nodes explained in other answers (created with mknod(2) or supplied by some devfs), Linux has other “magical” files provided by special virtual file systems, in particular in
/proc/ (see proc(5), read about procfs) and in
/sys/ (read about sysfs).
These pseudo files (which appear -e.g. to stat(2)- as ordinary files, not as devices) are a virtual view provided by the kernel; in particular, reading from
/proc/ (e.g. with
cat /proc/$$/maps, or by open(2)-ing
/proc/self/status in your program) generally does not involve any physical I/O from disk or network, so is quite fast.
To create some additional pseudo-file in
/proc/ you generally should write your own kernel module and load it (see e.g. this).