1.文件描述符匹配规则
文件描述符对应的分配规则是什么?
从0下标开始,寻找最小的没有没使用的数组位置,它的下标就是新文件的文件描述符
int main()
{
close(1);
int fd = open("log.txt", O_CREAT|O_WRONLY|O_TRUNC, 0666);
if(fd < 0)
{
perror("open");
return 1;
}
const char *msg = "hello Linux\n";
int cnt = 5;
while(cnt)
{
write(1, msg, strlen(msg));
cnt--;
}
close(fd);
return 0;
}
比如这个地方我们把原本默认开启下标1 stdout
关闭掉
因此再创建文件log.txt是从1的位置开始创建
因此这个时候write1不再是向stdout写入
而是向log.txt这个文件写入
当然这种做法太麻烦
我还要先关闭
于是便有了一个函数也就是dup2
2.dup2函数
int main()
{
int fd = open("log.txt", O_CREAT|O_WRONLY|O_TRUNC, 0666);
//这份代码是实现输出重定向>
//如果要实现追加式重定向>>就要将O_TRUNC改成O_APPEND
if(fd < 0)
{
perror("open");
return 1;
}
dup2(fd, 1);
//也可以dup2(fd,0)搭配read函数
//但是那就是从文件中读取 而不是键盘
close(fd);
const char *msg = "hello Linux\n";
int cnt = 5;
while(cnt)
{
write(1, msg, strlen(msg));
cnt--;
}
close(fd);
return 0;
}
我们通过dup2函数可以实现同样的功能
#include <unistd.h>
int dup2(int oldfd, int newfd);
将 oldfd 对应的文件描述符表项复制到 newfd,使得 newfd 和 oldfd 指向同一个文件、同一个文件偏移量、相同的文件状态标志(如读写权限)。
若 newfd 已经打开,dup2 会先关闭 newfd,再执行复制操作。
返回值 成功:返回 newfd(新的文件描述符)。
失败:返回 -1,并设置 errno(如 oldfd 无效、系统资源不足等)。
“先关后复制”:若 newfd 已打开,dup2 会先关闭它,再将 oldfd 复制过来。
oldfd 无效时的行为:若 oldfd 未打开(无效),dup2 直接失败,newfd 不会被关闭,返回 -1。 oldfd 与 newfd 相同时:dup2 不做任何操作,直接返回 newfd(因为两者已指向同 一文件)。
此外我们fprintf中的stdout默认是1
哪怕是说这个1被重定向成其他文件
或者stdout通过多次重定向到了其他下标
stdout都是1
进程历史打开的文件与进行的各种重定向关系都和未来进行程序替换无关!!程序替换,并不影响文件访问!!
此外我们要学会认识一些重定向的指令
./mytest >normal.log 2>err.log
#写全就是 ./mytest 1>normal.log 2>err.log
#./mytest:执行当前目录下名为 mytest 的可执行程序。
#>normal.log:将程序的标准输出(stdout,即正常运行时的信息输出) 重定向到 normal.log 文件中。
#若文件不存在则创建,若已存在则覆盖原有内容。
#2>err.log:2 代表标准错误输出(stderr,即程序运行时的错误、警告等信息)
#将其重定向到 err.log 文件中,同样遵循 “不存在则创建、存在则覆盖” 的规则。
./mytest 1>all.log 2>&1
#./mytest 启动 mytest 程序运行。
#1>all.log:程序的所有「正常输出」(stdout)不再显示到终端,而是写入 all.log 文件
#2>&1 程序的所有「错误输出」(stderr)不再显示到终端,
#而是跟随 stdout 的目标 —— 写入 all.log 文件。
#&1:表示「引用文件描述符 1(stdout)当前的输出目标」,而非创建一个名为 1 的文件
#(注意不能省略 &,否则会变成「把 stderr 写入名为 1 的文件」);
1336

被折叠的 条评论
为什么被折叠?



