1. Overview of File Descriptors
In Linux and other Unix-like operating systems, file descriptors are a core concept that provides a unified interface for programs to interact with files, devices, and other input/output (<span>I/O</span>) resources. Simply put, a file descriptor acts like a “ticket” or “handle” for programs to access these resources.
Whenever a program opens a file or creates an <span>I/O</span> resource (such as a socket or pipe), the operating system assigns a unique non-negative integer as the file descriptor. This number allows the program to perform read and write operations on the resource. In the Linux philosophy, “everything is a file“—whether it is a text file, keyboard input, or network communication, file descriptors enable all these resources to be handled in a consistent and efficient manner.
2. The Essence of File Descriptors
A file descriptor is a non-negative integer assigned by the operating system when a program opens a file or other <span>I/O</span> resource, serving as an identifier for the program to interact with that resource. For example:
- When opening a text file, the operating system might assign the file descriptor
<span>3</span> - When opening another file, it might assign the next available number
<span>4</span>
This simple mechanism allows programs to interact with different resources in a uniform way without worrying about the underlying implementation details. Whether reading from the keyboard or writing to a network socket, the same file descriptor interface can be used.
3. Standard File Descriptors
Each Linux process automatically receives three predefined file descriptors upon startup:
| Descriptor | Integer Value | Symbol Constant | Purpose |
|---|---|---|---|
<span>stdin</span> |
0 | <span>STDIN_FILENO</span> |
Standard input (default keyboard input) |
<span>stdout</span> |
1 | <span>STDOUT_FILENO</span> |
Standard output (default screen output) |
<span>stderr</span> |
2 | <span>STDERR_FILENO</span> |
Standard error (default error message output) |
3.1 Standard Input (stdin) – Descriptor: 0
The standard input stream is used to receive input data, defaulting to reading from the keyboard but can be redirected to files or pipes. Programs use <span>stdin</span> to receive user interaction input or process external data sources.
When content is entered in the terminal and the enter key is pressed, the data is sent to the program’s <span>stdin</span>. Additionally, the <span>stdin</span> stream can also read input from files or other programs through the <span>shell</span> redirection operator (<span><</span>).
For example, here is a simple script that gets input from the user and prints it out:
#!/bin/bash
# Prompt the user for their name
echo -n "请输入您的姓名:"
# Read input from the user
read name
# Print greeting message
echo "你好,$name!"
The output is as follows:
请输入您的姓名:张三
你好,张三!
Input streams can also be automated through redirection. For example, create a text file named <span>input.txt</span> containing the name “张三”, and then use <span><</span> to redirect the input stream:
./script.sh < input.txt
This way, the program reads data directly from the file without waiting for user input.
3.2 Standard Output (stdout) – Descriptor: 1
The standard output stream is used to display normal output generated by the program, defaulting to the terminal screen but can be redirected to files or other programs.
Programs use <span>stdout</span> to print results or messages, and this stream can be redirected to files or other programs using <span>shell</span> operators (<span>></span> or <span>|</span>).
For example, here is a simple script that prints a message to standard output:
#!/bin/bash
# Print message to standard output
echo "这是标准输出。"
The output is as follows:
这是标准输出。
If you want to redirect the output to a file instead of displaying it on the terminal screen, you can use <span>></span>, as shown below:
./stdout.sh > output.txt
You can also redirect the output of commands to a text file:
ls > output.txt
3.3 Standard Error (stderr) – Descriptor: 2
The standard error stream is used to display error messages and diagnostic information, separated from <span>stdout</span> for independent error handling.
For example, here is a script that triggers a <span>stderr</span> signal (simulating an error execution using <span>exit 1</span>):
#!/bin/bash
# Print message to standard output
echo "这是标准输出。"
# Print error message to standard error
echo "这是一个错误消息。" >&2
# Exit with a non-zero status indicating an error
exit 1
If this script is executed, it will simply print “这是一个错误消息。” To better understand, you can redirect the output and error to different files. For example, redirect the error message to <span>stderr.log</span> and the normal output to <span>stdout.log</span>:
./stderr.sh > stdout.log 2> stderr.log
4. Types of File Descriptor Limits
The Linux kernel sets limits on the number of file descriptors that a process can use. These limits help manage system resources and prevent a single process from consuming too much.
Different types of limits serve specific purposes:
- Soft Limit: The default maximum number of file descriptors a process can open. Users can temporarily increase this limit within their session up to the hard limit.
- Hard Limit: The absolute maximum number of file descriptors a process can open. Only system administrators can increase this limit to ensure system stability.
- Process-Level Limit: Each process has its own file descriptor limit, inherited from its parent process, to prevent a single process from overusing resources.
- System-Level Limit: The total number of file descriptors available to all processes in the system. This ensures fairness and prevents global resource exhaustion.
- User-Level Limit: Custom limits set for specific users or groups to allocate resources according to their needs.
Conclusion
File descriptors serve as the foundational mechanism for <span>I/O</span> operations in Linux systems, providing a unified and efficient way for programs to access resources. Understanding standard file descriptors (<span>stdin/stdout/stderr</span>) and their redirection techniques is a key skill in Linux system administration. Additionally, understanding the various types of file descriptor limits aids in resource management and performance tuning.
