There is not really a more specific term. In traditional Unix, file descriptors reference entries in the file table, entries of which are referred to as files, or sometimes open files. This is in a specific context, so while obviously the term file is quite generic, in the context of the file table it specifically refers to open files.
Files on disk are often referred to as inodes, although technically the inode is the metadata portion of the file. However since the relationship between the inode and the data blocks is one-to-one, referring to an inode implicitly refers to the data to which it points. More modern filesystems may support features such as copy-on-write where data blocks may be shared, so this is not universally true, but is for traditional Unix. However, given the term filesystem, it is no small leap to consider the contents of that to be files.
inodes are also read into memory as in-core inodes when a file on disk is opened, and maintained in the inode table, but that is one level of indirection further than you are asking.
This leads to the conflict in terminology: files on disk (referenced by an inode), and open files (referenced by entries in the file table).
I would suggest that "open file" or "file table entry" are both adequate descriptions of what you are looking to describe.
One reasonably concise reference I found is at: http://www.hicom.net/~shchuang/Unix/unix4.html. References of the form (Bach nn) are references to the book The Design Of The Unix Operating System by Maurice J. Bach.
No, you certainly don't want to close file descriptors 0, 1 and 2.
If you do so, the first time the application opens a file, it will become stdin/stdout/stderr...
For instance, if you do:
echo text | tee file >&-
When tee
(at least some implementations, like busybox') opens the file for writing, it will be open on file descriptor 1 (stdout). So tee
will write text
twice into file
:
$ echo text | strace tee file >&-
[...]
open("file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
read(0, "text\n", 8193) = 5
write(1, "text\n", 5) = 5
write(1, "text\n", 5) = 5
read(0, "", 8193) = 0
exit_group(0) = ?
That has been known to cause security vulnerabilities. For instance:
chsh 2>&-
And chsh
(a setuid application) may end up writing error messages in /etc/passwd
.
Some tools and even some libraries try to guard against that. For instance GNU tee
will move the file descriptor to one above 2 if the files it opens for writing are assigned 0, 1, 2 while busybox tee
won't.
Most tools, if they can't write to stdout (because for instance it's not open), will report an error message on stderr (in the language of the user which means extra processing to open and parse localisation files...), so it will be significantly less efficient, and possibly cause the program to fail.
In any case, it won't be more efficient. The program will still do a write()
system call. It can only be more efficient if the program gives up writing to stdout/stderr after the first failing write()
system call, but programs generally don't do that. They generally either exit with an error or keep on trying.
Best Answer
The
/proc/PID/fd/NUM
symlinks are quasi-universal on Linux, but they don't exist anywhere else (except on Cygwin which emulates them)./proc/PID/fd/NUM
also exist on AIX and Solaris, but they aren't symlinks. Portably, to get information about open files, installlsof
.Unices with
/proc/PID/fd
Linux
Under Linux,
/proc/PID/fd/NUM
is a slightly magic symbolic link to the file that the process with the ID PID has open on the file descriptor NUM. This link is magic in that, for example, it can be used to access the file even if the file is removed. The link will track the file through renames, too./proc/self
is a magic symbolic link which points to/proc/PID
where PID is the process that accesses the link.This feature is present on virtually all Linux systems. It's provided by the driver for the proc filesystem, which is technically optional but used for so many things (including making the
ps
work — it reads from/proc/PID
) that it's almost never left out even on embedded systems.Cygwin
Cygwin emulates Linux's
/proc/PID/fd/NUM
(for Cygwin processes) and/proc/self
.Solaris (since version 2.6), AIX
There are
/proc/PID/fd
entries for each file descriptor, but they appear as the same type as the opened file, so they provide no information about the path of the file. They do however report the samestat
information asfstat
would report to the process that has the file open, so it's possible to determine on which filesystem the file is located and its inode number. Directories appear as symbolic links, however they are magic symlinks which can only be followed, andreadlink
returns an empty string.Under AIX, the
procfiles
command displays some information about a process's open files. Under Solaris, thepfiles
command displays some information about a process's open files. This does not include the path to the file (on Solaris, it does since Solaris 10, see below).Solaris (since version 10)
In addition to
/proc/PID/fd/NUM
, modern Solaris versions have/proc/PID/path/NUM
which contains symbolic links similar to Linux's symlinks in/proc/PID/fd/NUM
. Thepfiles
command shows information about a process's open files, including paths.Plan9
/proc/PID/fd
is a text file which contains one record (line) per file descriptor opened by the process. The file name is not tracked there.QNX
/proc/PID/
is a directory, but it doesn't contain any information about file descriptors.Unices with
/proc
but no direct access to file descriptors(Note: sometimes it's possible to obtain information about a process's open files by riffling through its memory image which is accessible under
/proc
. I don't count that as “direct access”.)Unices where
/proc/PID
is a fileThe proc filesystem itself started out in UNIX 8th edition, but with a different structure, and went through Plan 9 and back to some unices. I think that all operating systems with a
/proc
have an entry for each PID, but on many systems, it's a regular file, not a directory. The following systems have a/proc/PID
which needs to be read withioctl
:MINIX 3
MINIX 3 has a procfs server which provides several Linux-like components including
/proc/PID/
directories. However there is no/proc/PID/fd
.FreeBSD
FreeBSD has
/proc/PID/
directories, but they do not provide information about open file descriptors. (There is however/proc/PID/file
which is similar to Linux's/proc/PID/exe
, giving access to the executable through a symbolic link.)FreeBSD's procfs is deprecated.
Unices without
/proc
File descriptor information through other channels
Fuser
The
fuser
command lists the processes that have a specified file open, or a file open on the specified mount point. This command is standard (available on all XSI-compliant systems, i.e. POSIX with the X/Open System Interface Extension).You can't go from a process to file names with this utility.
Lsof
Lsof stands for “list open files”. It is a third-party tool, available (but usually not part of the default installation) for most unix variants. Obtaining information about open files is very system-dependent, as the analysis above might have made you suspect. The lsof maintainer has done the work of combining it all under a single interface.
You can read the FAQ to see what kinds of difficulties lsof has to put up with. On most unices, obtaining information about the names of open files requires parsing kernel data structures. Quoting from FAQ 3.3 “Why doesn't lsof report full path names?”:
If you need to parse information from
lsof
's output, be sure to use the-F
mode (one field per line), preferably the-F0
mode (null-delimited fields). To get information about a specific file descriptor of a specific process, use the-a
option with-p PID
and-d NUM
, e.g.lsof -a -p 123 -d 0 -F0n
./dev/fd/NUM
for file descriptors of the current processMany unix variants provide a way to for a process to access its open files via a file name: opening
/dev/fd/NUM
is equivalent to callingdup(NUM)
. These names are useful when a program wants a file name but you want to pass an already-open file (e.g. a pipe or socket); for example the shells that implement process substitution use them where available (using a temporary named pipe where/dev/fd
is unavailable).Where
/dev/fd
exists, there are also usually (always?) synonyms (sometimes symbolic links, sometimes hard links, sometimes magic files with equivalent properties)/dev/stdin
=/dev/fd/0
,/dev/stdout
=/dev/fd/1
,/dev/stderr
=/dev/fd/2
./dev/fd
is a symbolic link to/proc/self/fd
./dev/fd
are character devices. They usually appear whether the file descriptor is open or not, and entries may not be available for file descriptors above a certain number./dev/fd
directory which follows the open descriptors of the calling process. A static/dev/fd
is available if/dev/fd
is not mounted./dev/fd
is provided via fdfs./dev/fd
on AIX or HP-UX.