前言:
在linux中,文件重定向(file redirection)是指将命令的输入和输出重定向到文件或其他设备,而不是默认的标准输入(stdin)和标准输出(stdout)。它是通过不同的符号来实现的。
重定向
标准输入重定向 (<)
标准输入重定向使用 < 符号将文件的内容传递给命令作为输入。例如,假设你有一个包含文本的文件,你可以将该文件的内容作为输入传递给命令进行处理。
示例:
- 将文件内容作为命令的输入:
wc < text.txt
这个命令会计算 log.txt 文件中的行数、字数和字符数。

输出重定向(> 和 >>)
标准输出重定向 (>) 是将命令的输出从默认的屏幕(标准输出)转向一个指定的文件。这个操作是通过 > 符号来实现的,它会将命令的标准输出写入到文件中。如果文件已经存在,重定向操作会覆盖原有的内容;如果文件不存在,它会新建一个文件。
>(输出重定向):将命令的标准输出重定向到文件,如果文件已存在,它会覆盖文件内容。
示例:
echo hello linux > log.txt
该命令会将 "hello linux 输出到 log.txt 文件,如果文件已存在,文件内容会被覆盖。

>>(追加输出):将命令的标准输出追加到文件的末尾,而不是覆盖。
示例:
echo "hello linux" >> log.txt
该命令将 hello linux 追加到 log.txt 文件的末尾。

标准错误输出重定向 (2>)
ls non_existent_file 2> error.log
- 打开
error.log文件。 - 关闭标准错误输出(文件描述符 2)。
- 使用
dup2()将文件描述符指向error.log。 - 将错误信息(例如“没有该文件或目录”)写入
error.log。
dup函数
在linux中,dup(duplicate)是一种系统调用,用于复制文件描述符。它允许一个进程为已经打开的文件描述符创建一个新的文件描述符,使得新旧描述符指向同一个文件或输入输出流。dup 通常用于文件重定向操作或管理多个文件描述符。
dup:创建一个新的文件描述符,指向与原始文件描述符相同的文件或流。dup2:类似于dup,但允许指定新文件描述符。
dup 系统调用
函数原型:
int dup(int oldfd);
- 功能:创建一个新的文件描述符,它与
oldfd指向相同的文件。新文件描述符是最小的未使用的文件描述符。 - 返回值:返回新的文件描述符,如果出错则返回
-1
dup2 系统调用
函数原型:
int dup2(int oldfd, int newfd);
功能:将 oldfd 复制到 newfd,如果 newfd 已经打开,会先关闭它。与 dup 的区别在于,dup2 允许指定新文件描述符。
示例:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
int main()
{
// 使用 o_trunc 和 o_creat 创建或打开 log.txt 文件,如果文件存在则清空文件内容
int fd = open("log.txt", o_trunc | o_creat | o_wronly, 0666);
if(fd < 0)
{
// 如果打开文件失败,输出错误信息并返回 -1
perror("open");
return -1;
}
// 关闭标准输出文件描述符 (stdout), 即文件描述符 1
close(1);
// 将标准输出文件描述符重定向到 fd 文件描述符 (指向 log.txt)
dup2(fd, 1);
// 要写入文件的消息
const char* msg = "hello linux\n";
// 设置写入消息的次数
int cnt = 5;
// 循环写入消息 5 次
while(cnt--)
{
// 使用 write 函数将消息写入标准输出 (实际上是 log.txt 因为 stdout 已被重定向)
write(1, msg, strlen(msg));
}
return 0; // 程序成功结束
}
解释:
- 打开文件:首先打开(或创建)一个名为
log.txt的文件,并设置权限为0666(允许所有用户读写)。o_trunc表示如果文件存在则清空文件内容,o_creat表示如果文件不存在则创建该文件,o_wronly表示文件以写模式打开。 - 关闭标准输出:通过
close(1)关闭标准输出文件描述符(通常是终端输出,文件描述符 1)。这意味着之后的标准输出操作将不再输出到终端,而是输出到其他位置。 - 重定向标准输出:
dup2(fd, 1)将文件描述符 1(标准输出)重定向到文件描述符fd,即log.txt文件。此时所有的标准输出操作将会写入到log.txt。 - 写入文件:程序使用
write(1, msg, strlen(msg))来将消息 “hello linux” 写入到标准输出(实际上是log.txt,因为已经重定向了标准输出)。这个操作会执行 5 次,最终在log.txt中写入 5 次 “hello linux”。 - 关闭文件:程序在结束前没有显式关闭文件描述符
fd,因为程序结束时文件会自动关闭。
重谈输入重定向(>)
echo "hello, world!" > log.txt
- 打开文件:shell 会用
open("output.txt", o_wronly | o_creat)打开文件。 - 关闭标准输出:shell 会用
close(1)关闭标准输出文件描述符。 - 复制文件描述符:shell 使用
dup2(fd, 1)将标准输出重定向到文件output.txt。 - 执行命令:命令
echo会将输出写入文件,而不是终端。
stdout 和 stderr
在 linux 系统中,stdout 和 stderr 都是进程的标准输出流,它们通过文件描述符进行管理。它们的作用和使用方式有所不同,主要体现在它们各自用于处理正常输出和错误输出。
stdout(标准输出):用于输出正常结果,默认文件描述符为 1。stderr(标准错误输出):用于输出错误信息,默认文件描述符为 2。- 重定向:你可以使用
>或>>重定向标准输出,而使用2>或2>>重定向标准错误输出。你还可以通过&>或2>&1合并两者的输出。
示例:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
int main()
{
fprintf(stdout, "hello normal message\n");
fprintf(stdout, "hello normal message\n");
fprintf(stdout, "hello normal message\n");
fprintf(stdout, "hello normal message\n");
fprintf(stdout, "hello normal message\n");
fprintf(stderr, "hello error message\n");
fprintf(stderr, "hello error message\n");
fprintf(stderr, "hello error message\n");
fprintf(stderr, "hello error message\n");
fprintf(stderr, "hello error message\n");
return 0;
}
待程序生成exe文件(file),分别执行:
./file > output.txt
./file > error.txt
./file > log.txt 2>&1

第一条命令 (./file > output.txt)
- 这条命令将
file程序的标准输出(stdout)重定向到output.txt文件。 file程序生成的正常信息会被写入到output.txt中,且不会显示在终端上。
第二条命令 (./file 2> error.txt)
- 这条命令将
file程序的标准错误输出(stderr)重定向到error.txt文件。 - 错误信息将写入到
error.txt中,而不会显示在终端上。
第三条命令 (./file > log.txt 2>&1)
- 这条命令将
file程序的标准输出(stdout)和标准错误输出(stderr)都重定向到同一个文件log.txt。 > log.txt将标准输出重定向到log.txt,而2>&1会将标准错误重定向到标准输出的目标(即log.txt)。
重定向总结
步骤:
- 打开目标文件:通过系统调用
open打开目标文件,获取文件描述符。 - 关闭标准输入输出文件描述符:使用
close(0)或close(1)关闭标准输入或标准输出的文件描述符。 - 复制文件描述符:使用
dup2(fd, 1)将标准输入输出或错误输出的文件描述符重定向到目标文件。
标准错误重定向到标准输出的目标(即log.txt)。
以上就是linux文件重定向的高级技巧与实践的详细内容,更多关于linux文件重定向的资料请关注代码网其它相关文章!
发表评论