【探索Linux】文件描述符 | 重定向 | 基础IO —— 强大的命令行工具 P.12

这篇具有很好参考价值的文章主要介绍了【探索Linux】文件描述符 | 重定向 | 基础IO —— 强大的命令行工具 P.12。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【探索Linux】文件描述符 | 重定向 | 基础IO —— 强大的命令行工具 P.12,Linux,linux,运维,开发语言,服务器

前言

前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的一些知识,也学习了一些Linux的基本操作,也了解并学习了有关Linux开发工具vim 、gcc/g++ 使用、yum工具以及git 命令行提交代码也相信大家都掌握的不错,上一篇文章我们了解了基础IO,文件操作,今天博主带大家了解一下 —— 文件描述符及重定向, 下面话不多说坐稳扶好咱们要开车了!!!😍

一、open()函数返回值

在认识返回值之前,先来认识一下两个概念: 系统调用库函数。上篇文章中我们提到的 fopenfclosefreadfwrite 都是C标准库当中的函数,我们称之为库函数(libc)。而, openclosereadwritelseek 都属于系统提供的接口,称之为系统调用接口

在Linux中,open()函数是用于打开文件的系统调用,它返回文件描述符。文件描述符是一个非负整数,用于唯一标识打开的文件。

open()函数的返回值有以下几种可能:

  • 如果成功打开文件,则返回一个新分配的文件描述符
  • 如果发生错误,返回-1,并可以使用全局变量errno获取具体的错误代码。

常见的错误代码包括:

  • EACCES:权限不足,无法访问指定文件。
  • ENOENT:文件不存在。
  • EISDIR:指定路径是一个目录。
  • EMFILE:进程已经达到了最大允许的打开文件数。
  • ENFILE:系统已经达到了最大允许的打开文件数。

使用时,我们一般需要检查open()函数的返回值是否为-1来判断是否出错,然后再根据具体的错误代码进行相应的处理。

二、文件描述符fd

1. 文件描述符的分配规则

文件描述符(File Descriptor)是一个整数,它用于标识一个进程打开的文件。在Unix/Linux系统中,每个进程都有一个文件描述符表(File Descriptor Table),用于管理打开的文件。文件描述符表是一个数组,每个元素表示一个打开的文件,而文件描述符就是数组的下标。

在Linux中,每个进程都有一个进程描述符(Process Descriptor)。进程描述符中包括一个文件描述符表,以及其他重要的信息,例如进程ID、进程状态等。当进程打开一个文件时,内核会从可用的文件描述符中选择一个最小的数字,并将其分配给该文件。这个数字就是文件描述符

文件描述符一般从3开始分配,因为0、1、2已经被预留给标准输入、输出、错误了。当进程打开一个文件时,内核会从当前可用的文件描述符中选择一个最小的数字,并将其分配给该文件。如果所有的文件描述符都已经被占用,再次打开文件就会返回错误。

当进程关闭一个文件时,相应的文件描述符就会变为可用状态,可以重新分配给其他文件。文件描述符的数目是有限的,通常与操作系统的版本、硬件配置等有关。

🚨🚨注意同一个进程中不同的文件描述符可以引用同一个文件,也就是说,打开同一个文件多次会得到不同的文件描述符。每个文件描述符都有自己的读写指针(File Offset),因此在不同的文件描述符上读写同一个文件,文件指针会互相独立,互不影响。

另外,在多进程编程中,父子进程共享文件描述符表。也就是说,如果一个进程打开了一个文件,并创建了一个子进程,那么子进程也会继承父进程的文件描述符表,包括已经打开的文件。这样,子进程就可以操作父进程已经打开的文件了。如果需要让子进程关闭父进程打开的文件,可以在fork()调用之后使用close()函数关闭不需要的文件描述符。

2. 文件描述符0、1、2

Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0,标准输出1,标准错误2。这些文件描述符在进程启动时会自动打开,并与对应的设备文件关联起来。

具体来说:

  • 文件描述符0(stdin) 用于处理标准输入,也就是从键盘或管道中读取输入数据。
  • 文件描述符1(stdout) 用于处理标准输出,也就是将程序输出写入到屏幕上或者重定向到文件中。
  • 文件描述符2(stderr) **用于处理标准错误,也就是输出程序的错误信息到终端或者重定向到文件中。

这些文件描述符是预先打开的,因此无需使用open()函数来打开它们。使用时,可以直接使用文件描述符号码0、1、2来引用它们。
【探索Linux】文件描述符 | 重定向 | 基础IO —— 强大的命令行工具 P.12,Linux,linux,运维,开发语言,服务器

三、重定向

在Unix/Linux系统中,重定向是一种常用的操作,用于改变进程的标准输入、标准输出和标准错误输出的默认设备。通过重定向,可以将命令的输入来自文件,或者将输出和错误输出写入到文件中,而不是默认的终端设备

重定向可以使用以下符号进行操作:

  1. 标准输出重定向(>):使用大于号(>)将命令的标准输出写入到指定的文件中,并覆盖原有内容。如果文件不存在,则创建一个新文件。
    例如,将命令的输出写入到文件output.txt中:

    command > output.txt
    
  2. 标准输出追加重定向(>>):使用双大于号(>>)将命令的标准输出追加写入到指定的文件中,而不覆盖原有内容。如果文件不存在,则创建一个新文件。
    例如,将命令的输出追加写入到文件output.txt中:

    command >> output.txt
    
  3. 标准错误输出重定向(2>):使用大于号加数字2(2>)将命令的标准错误输出写入到指定的文件中,并覆盖原有内容。如果文件不存在,则创建一个新文件。
    例如,将命令的错误输出写入到文件error.txt中:

    command 2> error.txt
    
  4. 标准错误输出追加重定向(2>>):使用双大于号加数字2(2>>)将命令的标准错误输出追加写入到指定的文件中,而不覆盖原有内容。如果文件不存在,则创建一个新文件。
    例如,将命令的错误输出追加写入到文件error.txt中:

    command 2>> error.txt
    
  5. 标准输入重定向(<):使用小于号(<)将命令的标准输入从指定文件读取。
    例如,将命令的输入从文件input.txt中读取:

    command < input.txt
    

除了文件外,重定向还可以使用特殊设备:

  • /dev/null:空设备文件,将输出或错误输出重定向到/dev/null时,数据会被丢弃,类似于黑洞。例如:
    command > /dev/null   # 将命令的输出丢弃
    command 2> /dev/null  # 将命令的错误输出丢弃
    

重定向操作可以组合使用,例如:

command1 > output.txt 2>&1

上述命令将命令command1的标准输出和标准错误输出都写入到文件output.txt中。

🚨🚨注意重定向操作符(>、>>、2>、2>>、<)在使用时需要与命令之间有空格,否则会被当作命令的一部分处理。另外,重定向是由shell解释和处理的,不是由具体的命令实现的,因此在不同的shell中可能存在一些差异。

1. 重定向的本质

**重定向的本质是通过操作文件描述符来改变进程的输入输出。**当一个进程执行时,会从这三个文件描述符中读取输入或将输出写入其中。重定向就是改变这些文件描述符所对应的文件,从而改变进程的输入输出行为。

在重定向操作中,文件描述符0、1和2分别对应的是文件描述符表中的前三个元素,即0、1和2。通过操作文件描述符表,可以将文件描述符指向不同的文件或设备。

例如,当使用>符号重定向标准输出时,实际上是将文件描述符1所对应的文件更改为指定的文件。具体的操作步骤如下:

  1. 打开指定文件,获取其对应的文件描述符x。
  2. 将进程的文件描述符表中的1替换为x。

这样,当进程进行标准输出时,实际上是将数据写入到了指定的文件中。

类似地,其他重定向操作也是通过类似的方式改变文件描述符表中相应位置的文件描述符。

🚨🚨注意重定向操作只影响当前进程以及其子进程,不会影响其他进程。每个进程都有自己独立的文件描述符表,互不干扰。

⭕图解

【探索Linux】文件描述符 | 重定向 | 基础IO —— 强大的命令行工具 P.12,Linux,linux,运维,开发语言,服务器

2. dup2 系统调用函数

dup2是Unix/Linux系统提供的系统调用函数之一,用于复制文件描述符并将其关联到指定的文件描述符

使用dup2函数可以方便地进行文件描述符的重定向,实现输入输出的灵活控制

函数原型如下:

#include <unistd.h>
int dup2(int oldfd, int newfd);

参数说明:

  • oldfd:要被复制的文件描述符。
  • newfd:新的文件描述符,将与oldfd关联。

函数功能:
dup2函数将文件描述符oldfd复制到newfd,并返回一个新的文件描述符。如果newfd已经打开,则将先关闭它。新的文件描述符将继承oldfd的文件状态标志(例如,文件偏移量、文件访问模式等)。

函数返回值:

  • 成功时,返回新的文件描述符;失败时,返回-1,并设置errno变量来指示错误类型。

使用示例(输入重定向):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    int fd = open("file.txt", O_RDONLY);  // 打开文件,获取文件描述符
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    int newfd = dup2(fd, STDOUT_FILENO);  // 将文件描述符复制到标准输出
    if (newfd == -1) {
        perror("dup2");
        exit(EXIT_FAILURE);
    }

    printf("Hello, world!\n");  // 标准输出已被重定向到文件

    close(fd);  // 关闭文件描述符
    close(STDOUT_FILENO);
    return 0;
}

上述示例代码中,首先使用open函数打开一个文件,并获取文件描述符fd。然后,使用dup2函数将文件描述符fd复制到标准输出的文件描述符(即1),返回新的文件描述符newfd。接下来,通过printf函数向标准输出写入内容,实际上是将数据写入到文件中。最后,关闭文件描述符和标准输出的文件描述符。

温馨提示

感谢您对博主文章的关注与支持!如果您喜欢这篇文章,可以点赞、评论和分享给您的同学,这将对我提供巨大的鼓励和支持。另外,我计划在未来的更新中持续探讨与本文相关的内容。我会为您带来更多关于Linux以及C++编程技术问题的深入解析、应用案例和趣味玩法等。如果感兴趣的话可以关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。我们期待与您建立更紧密的互动,共同探索Linux、C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!
【探索Linux】文件描述符 | 重定向 | 基础IO —— 强大的命令行工具 P.12,Linux,linux,运维,开发语言,服务器文章来源地址https://www.toymoban.com/news/detail-713923.html

到了这里,关于【探索Linux】文件描述符 | 重定向 | 基础IO —— 强大的命令行工具 P.12的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux】基础IO(一) :文件描述符,文件流指针,重定向

    🍎 作者: 阿润菜菜 📖 专栏: Linux系统编程 是不是只有C/C++有文件操作呢?python、java、go等文件接口操作的方法是不太一样的,那如何理解这种现象?有没有统一的视角去看待所有的语言文件操作呢?—我们今天从系统视角去理解 ---- 实际都是通过系统调用来访问 文件=内

    2024年01月18日
    浏览(47)
  • 【Linux】基础IO_文件描述符与重定向

    环境:centos7.6,腾讯云服务器 Linux文章都放在了专栏:【 Linux 】欢迎支持订阅 相关文章推荐: 【Linux】冯.诺依曼体系结构与操作系统 【C/进阶】如何对文件进行读写(含二进制)操作? 【Linux】基础IO_文件操作 在前文中学习了open函数,我们知道 open函数的返回值就是文件描

    2024年02月03日
    浏览(72)
  • [Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向)

            hello,大家好,这里是bang___bang_ ,今天和大家谈谈Linux中的基础IO,包含内容有对应的系统文件I/O接口,文件描述符,理解重定向。    目录 1️⃣初识文件 2️⃣ 系统文件I/O接口 🍙open 🍙write 🍙read 🍙close 3️⃣文件描述符 🍙012 🍙内核中文件描述符的探究 🍙分配

    2024年02月12日
    浏览(36)
  • 【Linux】基础IO——系统文件IO&&fd&&重定向

    大家好我是沐曦希💕 空文件,也要在磁盘占据空间,因为文件也有属性,属性也属于数据,需要空间进行存储。所以 文件包括内容和属性 所以 对文件操作就是对内容或者对属性进行操作,或者对内容和属性进行操作。 文件具有唯一性,所以在 标定一个文件时候,必须使用

    2024年02月02日
    浏览(45)
  • 【Linux】基础 IO(文件描述符)-- 详解

    1、 文件的宏观理解 文件在哪呢? 从广义上理解,键盘、显示器、网卡、声卡、显卡、磁盘等几乎所有的外设都可以称之为文件,因为 “Linux 下,一切皆文件”。 从狭义上的理解, 文件在 磁盘(硬件) 上放着 ,只有操作系统才能真正的去访问磁盘。磁盘是一种永久存储介

    2024年03月24日
    浏览(47)
  • 系统文件IO、文件描述符fd、重定向、文件系统、动态库和静态库

    C文件接口 C文件接口都是封装了系统的文件接口,学习系统的文件接口有利于更熟悉文件的操作。 open函数 头文件 #include sys/types.h #include sys/stat.h #include fcntl.h 函数描述 int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); 参数 pathname: 要打开或创建的目

    2024年02月07日
    浏览(41)
  • 【探索Linux】—— 强大的命令行工具 P.13(文件系统 | 软硬链接 | 动态库和静态库)

    在计算机科学领域中,Linux 系统一直以来都是备受推崇的操作系统之一。其中,文件系统、软硬链接、动态库和静态库是 Linux 系统中非常重要的概念,在实际应用中扮演着不可或缺的角色。 在上一篇文章中,我们了解了 Linux 系统中文件描述符、重定向以及基础 IO 操作的相关

    2024年02月04日
    浏览(50)
  • 【Linux】文件的描述符和重定向

    C语言的文件读写操作 文件写入 fputs int fputs(const char *s, FILE *stream); s:要写入的字符串 stream:要写入对应的目标文件 文件输出(只可以在文件读的环境下运行 r) fgets char *fgets(char *s, int size, FILE *stream); s:要保存到的目标位置 size:输出多少字节 stream:输出的目标文件 文件写

    2024年02月12日
    浏览(45)
  • 【Linux】文件描述符与重定向操作

    收录于【Linux】文件系统 专栏 对于Linux下文件的写入与读取,以及文件原理还有疑惑的可以看看上一篇文章浅谈文件原理与操作。 目录 系列文章 再谈文件描述符 IO函数的本质 一切皆文件 文件重定向 原理 系统接口 🍧上一篇文章中,我们就提到了 open 的返回值即 fd ,又称

    2024年02月09日
    浏览(39)
  • Linux中的文件描述符和重定向

    文件描述符概念 我们在使用系统调用进行文件操作的时候 这里的open返回值就是一个文件描述符简称fd。 文件描述符其实就是一个从3开始的小整数,文件描述符是小整数的原因是因为文件描述符实际是文件描述符表这个数组的下标。 为什么从3开始,是因为系统默认打开了三

    2023年04月10日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包