前言:
在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文件重定向的资料请关注代码网其它相关文章!
发表评论