Linux重定向:深入理解与实践

简介: Linux重定向:深入理解与实践

引入

文件描述符的分配规则

       在Linux系统中,文件描述符是一个数字,这个数字是用于表示打开的文件、管道和网络连接等进程所操作对象的标识符。文件描述符的分配规则遵循最小分配原则,也就是寻找未被占用的最小的文件描述符来使用。

       在Linux进程中,默认会有三个已经打开的文件描述符,对应的是标准输入(0)、标准输出(1)和标准错误(2)。这三个文件描述符分别对应键盘、显示器和打印机等物理设备。

       当我们需要打开新的文件时,系统会根据最小分配原则找到下一个可用的文件描述符进行分配。一般来说,新打开的文件会占用文件描述符3(如果0、1、2尚未被占用),接着是文件描述符4,以此类推。特别的,如果0、1或2已被关闭,那么新打开的文件的文件描述符可能会被赋值为0或1或2。


      需要注意的是,虽然文件描述符是连续分配且依次增大的,但它们的起始值并不从0开始,而是从3开始。


       🌰


       在学习完Linux下的系统文件操作后,我们都知道Linux下一切皆文件,我们可以对文件进行打开、读、写、关闭等操作。而系统默认会帮我们打开三个文件,分别为标准输入、标准输出和标准出错处理,即:stdin、stdout、stderr。这三个文件分别对应文件描述符0、1、2。那么如果我们关闭了其中的一个文件,再额外打开个新的文件会这么样呢?如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FI "fi.txt"
int main()
{
  umask(0);
    close(1);//关闭输出流
    int fd = open(FI, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    printf("hello!\n");
    printf("hello!\n");
    printf("hello!\n");
    printf("hello!\n");
    printf("hello!\n");
    printf("hello!\n");
    printf("hello!\n");
    printf("my fd is %d\n",fd); 
    return 0;
}


       对上述代码的情况可见:我们关闭了输出流的文件,新打开了一个文件,而使用printf进行打印操作。需要注意的是:printf、scanf都是默认的输入输出流,也就是说他们是按照stdin、stdout来进行对应的操作的。而此时printf非但没有把字符打印到显示器上反而打印到了新开的那个文件里,并且对应的文件描述符居然是1!这就说明了新开文件的文件描述符是遵守有空就补、从小到大使用的规律。


       大致的操作如下:

       对此,这也引出了我们重定向的概念—重定向是一种改变标准输入或输出默认执行方式的操作,无需大量的鼠标和键盘操作就可以完成数据的转移。


重定向理解

什么是重定向?

       在Linux系统中,重定向的本质是修改原来默认的执行方式,对系统命令的执行过程进行重新定义。它主要涉及两个方面:输入重定向和输出重定向。


  • 输入重定向:指的是将一个文件的内容导入到命令中作为输入数据。这种方式可以使得命令的执行不再依赖键盘的输入,而是读取来自指定文件的数据,从而提高了效率和便捷性。
  • 输出重定向:指的是将命令的执行结果保存到文件中,而不是直接显示在显示器上。这种方式可以将命令的输出信息保存下来,以供后续分析和使用,避免了信息的丢失。

 说大白话就是:修改特性文件fd下标的内容,上层fd不变,底层fd指向的内容在改变

输出重定向

       我们通过关闭文件描述符1或者2,然后打开一个新的文件使得通过printf输出的内容输出到fi.txt文件中。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FI "fi.txt"
int main()
{
  umask(0);
    close(1);//关闭输出流
    int fd = open(FI, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    printf("output redirection!\n");
    printf("output redirection!\n");
    printf("output redirection!\n");
    printf("my fd is %d\n",fd); 
    return 0;
}.

输入重定向

       我们通过关闭文件描述符0,然后打开一个新的文件通过scanf从fi.txt中输入内容,然后再通过printf输出到显示器上。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FI "fi.txt"
int main()
{
  umask(0);
    close(1);//关闭输入流
    int fd = open(FI, O_RDONLY , 0666);
  char *st;
    scanf("%s",st);
    printf("%s\n",st);
    scanf("%s",st);
    printf("%s\n",st);
    scanf("%s",st);
    printf("%s\n",st);
    printf("my fd is %d\n",fd); 
    return 0;
}.

追加重定向

       本质还是和输出重定向一样关闭文件描述符1或者2,但是需要注意的是我们更改了打开文件的操作,把清空操作改为了追加操作。 O_TRUNC -> O_APPEND

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FI "fi.txt"
int main()
{
  umask(0);
    close(1);//关闭输出流
    int fd = open(FI, O_WRONLY | O_CREAT | O_APPEND,  0666);
    printf("append redirection!\n");
    printf("append redirection!\n");   
    printf("append redirection!\n");
    printf("my fd is %d\n",fd); 
    return 0;
}

dup2

       dup2函数是Unix/Linux系统中的一个系统调用函数,作用是复制文件描述符,并将其指定为新的文件描述符。其具体功能是将一个已存在的文件描述符复制到另一个新的文件描述符上,并且可以自定义新文件描述符的编号。系统中的手册如下:



       这个函数在C语言中常用于实现输入输出重定向。例如,可以先使用open()函数打开需要重定向的文件,然后使用dup2()函数将指定的文件描述符复制到新的文件描述符。这样就可以改变一个进程的标准输入、标准输出和标准错误输出的文件描述符指向,进而实现重定向的功能。


       dup2函数的原型为 int dup2 (int oldfd, int newfd); 其中,oldfd参数表示要被复制的文件描述符,newfd参数表示新的文件描述符。如果newfd已经打开,则先将其关闭。如果newfd等于oldfd,则dup2返回newfd, 而不关闭它。


     需要注意的是:dup2函数是dup()函数的“升级版“,因为与dup()只能复制一次不同,dup2可以无限次复制文件描述符。此外,如果复制成功,dup2函数会返回最小的尚未被使用过的文件描述符。

    🌰

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FI "fi.txt"
int main()
{
  umask(0);
    int fd = open(FI, O_WRONLY | O_CREAT | O_APPEND,  0666);
    dup2(fd,1);
    printf("append redirection!\n");
    printf("append redirection!\n");   
    printf("append redirection!\n");
    printf("my fd is %d\n",fd); 
    close(fd);
    return 0;
}

重新理解‘输入’和‘输出’重定向

       在Linux中,>、>>和<、<<是重定向操作符,用于将命令的输出或输入重定向到文件或管道。

      - >:将命令的标准输出重定向到一个文件中,如果该文件不存在则创建它,如果存在则覆盖原有内容。例如:ls > file.txt 会将ls命令的输出保存到file.txt文件中。

       - >>:将命令的标准输出追加到一个文件中,如果该文件不存在则创建它。例如:ls >> file.txt 会将ls命令的输出追加到file.txt文件中。

       - <:将一个文件的内容作为命令的标准输入。例如:sort < file.txt 会将file.txt文件的内容作为sort命令的输入。

       - <<:将多行文本作为命令的标准输入。例如:echo -e "line1 line2 line3" | cat << EOF 会将EOF标记之间的文本作为cat命令的输入。

       通过上面我们对于重定向的理解,我们也从本质上理解了重定向实际上做的是什么操作,即:修改底层fd的指向。接下来我们进一步学习对于输入和输出的重定向!


完整的重定向格式

       实际上,完整的重定向格式如下:

命令 fd>/>>/</<< 命令

🌰

标准输出重定向

标准错误重定向

标准输出以及标准错误重定向同一文件


                        感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o! 

相关文章
|
12天前
|
监控 算法 Linux
Linux内核锁机制深度剖析与实践优化####
本文作为一篇技术性文章,深入探讨了Linux操作系统内核中锁机制的工作原理、类型及其在并发控制中的应用,旨在为开发者提供关于如何有效利用这些工具来提升系统性能和稳定性的见解。不同于常规摘要的概述性质,本文将直接通过具体案例分析,展示在不同场景下选择合适的锁策略对于解决竞争条件、死锁问题的重要性,以及如何根据实际需求调整锁的粒度以达到最佳效果,为读者呈现一份实用性强的实践指南。 ####
|
12天前
|
缓存 监控 网络协议
Linux操作系统的内核优化与实践####
本文旨在探讨Linux操作系统内核的优化策略与实际应用案例,深入分析内核参数调优、编译选项配置及实时性能监控的方法。通过具体实例讲解如何根据不同应用场景调整内核设置,以提升系统性能和稳定性,为系统管理员和技术爱好者提供实用的优化指南。 ####
|
5月前
|
Ubuntu Linux vr&ar
IM跨平台技术学习(十二):万字长文详解QQ Linux端实时音视频背后的跨平台实践
本文详细记录了新版QQ音视频通话在 Linux 平台适配开发过程中的技术方案与实现细节,希望能帮助大家理解在 Linux 平台从 0 到 1 实现音视频通话能力的过程。
187 2
|
1月前
|
关系型数据库 MySQL Linux
Linux环境下MySQL数据库自动定时备份实践
数据库备份是确保数据安全的重要措施。在Linux环境下,实现MySQL数据库的自动定时备份可以通过多种方式完成。本文将介绍如何使用`cron`定时任务和`mysqldump`工具来实现MySQL数据库的每日自动备份。
82 3
|
2月前
|
监控 Linux 云计算
Linux操作系统在云计算环境中的实践与优化###
【10月更文挑战第16天】 本文探讨了Linux操作系统在云计算环境中的应用实践,重点分析了其在稳定性、安全性和高效性方面的优势。通过具体案例,阐述了Linux如何支持虚拟化技术、实现资源高效分配以及与其他开源技术的无缝集成。文章还提供了针对Linux系统在云计算中的优化建议,包括内核参数调整、文件系统选择和性能监控工具的应用,旨在帮助读者更好地理解和应用Linux于云计算场景。 ###
51 3
|
2月前
|
Ubuntu Linux
Linux实践|设置静态 IP 地址
Linux实践|设置静态 IP 地址
74 0
Linux实践|设置静态 IP 地址
|
4月前
|
存储 人工智能 数据管理
深入理解Linux操作系统之文件系统管理探索人工智能:从理论到实践的旅程
【8月更文挑战第30天】在探索Linux的无限可能时,我们不可避免地会遇到文件系统管理这一核心话题。本文将深入浅出地介绍Linux文件系统的基础知识、操作命令及高级技巧,帮助你更有效地管理和维护你的系统。从基础概念到实践应用,我们将一步步揭开Linux文件系统的神秘面纱。
|
4月前
|
存储 Unix Linux
Linux I/O 重定向与管道
【8月更文挑战第17天】重定向在Linux中改变命令I/O流向,默认有&quot;&gt;&quot;覆盖输出至文件及&quot;&gt;&gt;&quot;追加输出至文件末尾,便于保存结果;使用&quot;&lt;&quot;从文件读取输入而非键盘,高效处理数据。文件描述符如0(stdin)、1(stdout)、2(stderr)标识I/O资源,支持读写操作。管道以&quot;|&quot;连接命令,使前一命令输出成为后一命令输入,如排序用户或找出CPU占用最高的进程,构建复杂数据处理流程。
52 9
|
4月前
|
存储 Unix Linux
Linux I/O 重定向与管道
【8月更文挑战第14天】输出重定向可将命令结果存入文件,如`&gt;`覆盖写入或`&gt;&gt;`追加写入。输入重定向从文件读取数据,如`&lt;`代替键盘输入。这些操作利用文件描述符(如0:stdin, 1:stdout, 2:stderr)管理I/O。管道`|`连接命令,使前一命令输出作为后一命令输入,便于数据处理,如排序用户`sort -t: -k3 -n /etc/passwd | head -3`或查找CPU占用高的进程`ps aux --sort=-%cpu | head -6`。
46 4
|
4月前
|
Unix Linux Shell
Linux I/O 重定向简介
Linux I/O 重定向简介
42 2