The /proc Filesystem

In Unix, it seems almost everything can be treated like a file (Section 1.19). On many modern Unix systems, even processes are files — well, sort of. A special filesystem named /proc doesn't actually "contain" processes, but it lets you interact with them. Almost all of the "files" in /proc are plain text, so you can access them from scripts and programs, as well as from the command line. Of the systems I've checked, my Red Hat Linux 6.2 box (kernel version 2.2) seems to have the most in /proc, so I'll cover it. Please check your documentation — a proc(5) manual page, for instance — for the story on your system.

All /proc filesystems have one subdirectory for each process currently running on the system. Each of those process subdirectories is named for its PID (Section 24.3). Some versions of /proc also have other named files and subdirectories — and my system has a lot of them. Here's a partial listing of my /proc filesystem at the moment; I've left out a lot of the numbered subdirectories:

-F Section 8.10

$ ls -F /proc
1/        17415/    467/      cmdline      ksyms        pci
1047/     2/        482/      cpuinfo      loadavg      rtc
1052/     3/        5/        devices      locks        scsi/
1057/     345/      553/      dma          mdstat       self@
1287/     370/      593/      fb           meminfo      slabinfo
1289/     379/      594/      filesystems  misc         stat
14288/    393/      595/      fs/          modules      swaps
14289/    4/        596/      ide/         mounts       sys/
17409/    4017/     597/      interrupts   mtrr         tty/
17412/    407/      6/        ioports      net/         uptime
17413/    425/      apm       kcore        partitions   version
17414/    439/      bus/      kmsg

Linux system utilities like ps and pidof use information from /proc. Your programs can use it, too; there are some examples below. But it's also useful when you want to know something about your system. The "files" in /proc are most useful there. Let's look at a series of examples. We'll end with the numbered per-process "directories."

The sections below describe per-process subdirectories in /proc. One special directory is /proc/self. It has the unusual property of giving a different answer for every process that examines it: information about the current process. (This "directory" is actually a symbolic link (Section 10.4) to the directory numbered for the process' PID.)

For instance, a process can check its /proc/self/fd directory to see which files its file descriptors ( Section 36.15) are currently pointing to. This isn't just what type of file (disk file, tty (Section 2.7), pipe, etc.) but the actual full pathname of the file. If you're new to Unix, this may not seem too earth-shaking, but it's actually pretty amazing.

For a simple example, here's a shell script that lists its input and outputs. It then redirects its standard input (file descriptor 0) from /dev/null (Section 43.12) and lists again.

$ pwd
/tmp
$ tty
/dev/pts/5
$ cat showfds
#!/bin/sh
cd /proc/self/fd
ls -l
exec 0</dev/null
ls -l
$ ./showfds < somefile
total 0
lr-x------    1 jpeek    jpeek     64 Dec  2 09:03 0 -> /tmp/somefile
lrwx------    1 jpeek    jpeek     64 Dec  2 09:03 1 -> /dev/pts/5
lrwx------    1 jpeek    jpeek     64 Dec  2 09:03 2 -> /dev/pts/5
lr-x------    1 jpeek    jpeek     64 Dec  2 09:03 3 -> /tmp/showfds
total 0
lr-x------    1 jpeek    jpeek     64 Dec  2 09:03 0 -> /dev/null
lrwx------    1 jpeek    jpeek     64 Dec  2 09:03 1 -> /dev/pts/5
lrwx------    1 jpeek    jpeek     64 Dec  2 09:03 2 -> /dev/pts/5
lr-x------    1 jpeek    jpeek     64 Dec  2 09:03 3 -> /tmp/showfds

All versions of /proc that I've seen have subdirectories named for each process currently running on the system. Each subdirectory is named for the process PID (Section 24.3). Here are a series of examples of the useful info on my Linux system:

Go to http://examples.oreilly.com/upt3 for more information on: showenv

; Section 28.16

$ tr '\000' ' ' < /proc/861/cmdline; echo
tail -f /var/log/messages /var/log/maillog /u/jerry/tmp/startx.log

If you are curious about your system's hardware, a quick look at /proc/cpuinfo, /proc/interrupts, and /proc/ioports will help you size up the system. All the following examples came from a Red Hat Linux box, but you will find these proc files on most Linux and BSD systems. For instance, /proc/cpuinfo looks like this (on my system):

processor: 0
vendor_id: GenuineIntel
cpu family: 6
model: 6
model name: Celeron (Mendocino)
stepping: 0
cpu MHz: 400.918
cache size: 128 KB
fdiv_bug: no
hlt_bug: no
f00f_bug: no
coma_bug: no
fpu: yes
fpu_exception: yes
cpuid level: 2
wp: yes
flags: fpu vme de pse tsc msr pae mce cx8 sep mtrr pat pse36 mmx fxsr
bogomips: 799.53

The most important fields to notice are processor, model name, and cpu MHz since these identify how many CPUs are in the system, the model name (although this isn't always so clear in older Pentium models), and the CPU speed of your machine.

The other three proc files are important if you are installing hardware or trying to configure recently installed hardware. /proc/interrupts lists the hardware interrupt numbers and shows which devices are using which interrupt. On my machine, this looks like:

           CPU0
  0:   92887036          XT-PIC  timer
  1:     910141          XT-PIC  keyboard
  2:          0          XT-PIC  cascade
  3:          4          XT-PIC  serial
  5:    4794267          XT-PIC  eth0
  8:   11642728          XT-PIC  rtc
 10:   65248789          XT-PIC  es1371
 11:          0          XT-PIC  usb-uhci
 12:    5109157          XT-PIC  PS/2 Mouse
 14:     560048          XT-PIC  ide0
 15:     408739          XT-PIC  ide1
NMI:          0
ERR:          0

/proc/ioports lists the hardware I/O port ranges that all your systems devices use. This is a good file to examine if recently installed hardware can't be found in your drivers. Here's an abbreviated sample of my system's /proc/ioports.

03f6-03f6 : ide0
03f8-03ff : serial(auto)
0cf8-0cff : PCI conf1
4000-403f : Intel Corporation 82371AB PIIX4 ACPI
5000-501f : Intel Corporation 82371AB PIIX4 ACPI
c000-cfff : PCI Bus #01
d000-d01f : Intel Corporation 82371AB PIIX4 USB
d400-d43f : Ensoniq ES1371 [AudioPCI-97]
d800-d807 : Lucent Microelectronics 56k WinModem
dc00-dcff : Lucent Microelectronics 56k WinModem
e000-e0ff : PCI device 1186:1300 (D-Link System Inc)
f000-f00f : Intel Corporation 82371AB PIIX4 IDE

This file makes it easy to diagnosis hardware conflicts. However, if your system is working well, you probably won't be looking at any of these files much.

— JP