Linux基础IO

基础I/O       **
         

         回顾C库的 IO 接口
          linux下 IO 的系统调用接口
          文件流指针    文件描述符    文件重定向
          linux下ext2文件系统    indoe节点   
         软链接/硬链接     动态库/静态库生成
        
         1.回顾:fopen    fclose   fwrite   fread   fseek
                (fprintf fgets sprintf snprintf printf)
                 mode: r   r+    w  w+  a  a+
                          read  ret=0
         2.系统调用接口:  open   close  read   write    lseek
         
               write:
                    size_t write( int fd,const void *buf ,size_t count)
                    fd:     文件描述符
                    buf: 要写入的数据
                    count:要写入的数据长度
                    返回值:实际写入长度   失败:-1
              read:
                    size_t read(int fd,const void *buf ,size_t count)
                    fd:     文件描述符
                    buf: 要写入的数据
                    count:要写入的数据长度
                    返回值:实际读取字节长度   失败:-1
              lseek:
                   off_t lseek(int fd, off_t offset, int whence)
                   跳转到文件读写位置到whence位置偏移ofset个字节
                   fd:文件描述符
                   offset:偏移量
                   whence:要偏移的起始位置
              close(fd);   关闭文件
         3.文件描述符:非负整数
                    一个进程会打开很多文件,那么进程就需要对这些文件进行管理
             描述+组织       描述(结构体)     组织(结构体数组)
                     进程通过file结构体描述文件,并且使用结构体数组将这些描述组
             织起来进行管理,我们打开文件所获取的文件描述符其实就是这个数组
             中对应文件描述信息的下标。我们用户通过下标找到文件描述信息,进
             而对文件进行操作(操作句柄FILE)
             
          文件流指针与文件描述符:
                标准库接口的操作句柄是文件流指针
                系统调用接口的操作句柄是文件描述符
                文件流指针这个结构体中封装了文件描述符作为成员变量
          缓冲区:缓冲区是文件流指针的缓冲区    
          文件缓冲区: 向文件写入数据是先写入缓冲区,等待缓冲区满了,才
                        写入文件;文件流指针中包含了缓冲区普通文件不具备
                        换行刷新缓冲区功能,只有标准文件才有这个功能
          文件描述符的分配规则:
                 遵循最小未使用原则                   
          文件重定向:
                 本质是改变文件描述符下标对应的文件描述信息
                  int dup(int oldfd)               
                 让最小的未使用的fd指向oldfd位置
                 int  dup2(int oldfd,int newfd)
                 让newfd也指向oldfd指向的位置
            dup2:
                    >    清空文件原有内容,将新数据写入
                    >>   将新数据追加,写入到文件中
             1.解析命令,判断是否有重定向符号
             2.获取重定向文件名
             3.以相应方式打开文件
             4.重定向(dup2)不能在父进程中完成,因为一旦父进程重定向了
               shell程序后续的界面就打印不出来,都会写入到这个文件中
        
        4.linux下文件系统:管理磁盘文件
                交换分区+系统分区(每个文件都有自己的系统分区)
               inode节点(文件大小,权限,用户,时间,文件存储地址)

        目录和普通文件有什么区别?
             目录也是文件,只不过数据存储的是目录下的文件名和inode节点号
        cat file流程:通过文件名在目录中获取文件inode节点->通过inode节点找
             到数据存储位置->读取文件数据
        软连接和硬链接:
             硬链接:
                  ln a.txt b.txt
             软链接:
                  ln -s a.txt b.txt
            区别:
                软链接是一个类似于快捷方式的文件/硬链接是一个文件的别名
                硬链接文件具有相同的inode,所有硬链接文件通过inode操作数据
                软链接文件和源文件不是同一个文件,拥有不同的inode节点号,访
                问软链接文件,就是通过软链接文件中保存的源文件路径来访问文件
             删除源文件,软链接失效;但是硬链接不影响,只是链接数-1(当一个文
             件链接数为0时才真正删除一个文件,否则只是删除目录项)
             软链接可以针对目录创建,但是硬链接不可以
             软链接可以跨分区创建,硬链接不可以
        df:查看分区挂载情况
        linux下SATA接口类型硬盘命令方式:sda adb...
        在进行安装系统的时候可以对磁盘进行分区操作
        sda这块磁盘进行分区:sda1 sda2....
        用户可以将各个分区挂载在指定目录下,至少需要一块分区需要挂载在根目录
        跟磁盘及挂载相关命令: fdisk df -du
     
     5.动态库 / 静态库
         动态链接/静态链接
         生成一个库需要将所有目标文件集合到一起,生成一个打包后的代码库
         gcc -c  a.c -o a.o
         gcc -c  b.c -o b.o 
        如何生成动态库
          gcc -fPIC -c  b.c -o b.o 
          gcc --share b.o -o libmy_b.so
             -fPIC产生与位置无关代码
        如何生成静态库:
             gcc -c  b.c -o b.o 
            ar -cr libmyb.a b.o
        动态库命名:以lib为前缀, .so为后缀,中间是库名称
        静态库命名:以lib为前缀, .a为后缀,中间是库名称
        gcc 选项: -E -S -c -o -static -g 
                  
                  -fPIC:生成动态库需要--产生与位置无关代码
                  --share:生成共享库(动态库)而不是可执行程序
            ar:静态库链接器--用于生成静态库
                 -c 创建静态库
                 -r 模块替换                 
        链接库:
           动态库或静态库的链接:生成可执行程序时,系统需要所有库都在指
        定路径(/lib64)下,这时候才能找到这个库
        
         如果不想将库放到/lib64下,这时候可以指定库的查找路径
         gcc a.c -o a -L  ./ -lmy_b
         
         -L  指定库的搜索路径(默认路径找不到,就会到这里来)
         -l  指定要链接库的名称
       动态链接生成的可执行程序,需要动态库的存在并且存在于指定目录下
         因此动态库直接拷贝到/lib64下
        ldd a  查看一个可执行程序a所依赖的动态库

<think>首先,用户的问题是:“我想理解Linux基础IO中重定向的概念和定义 请问Linux基础IO重定向的定义及原理”。我需要基于提供的引用和系统指令来回答。 系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 参考站内引用: - [^1]: 讲解重定向的实现、本质、和进程替换之间的关系。 - [^2]: 文件操作原理和重定向,涉及文件描述符。 - [^3]: 重定向示例,说明标准输出和标准错误重定向。 - [^4]: 文件描述符的概念。 - [^5]: 文件操作命令的示例,如cp命令的备份。 我的回答需要集中在重定向的定义和原理上。定义应该简明扼要,原理则需要解释底层机制。 关键点: - **定义**:重定向是Linux中改变输入/输出源或目的地的过程。例如,将命令的输出从屏幕重定向到文件。 - **原理**:基于文件描述符。每个进程打开文件时,内核会分配一个文件描述符(如0为stdin,1为stdout,2为stderr)。重定向通过改变这些文件描述符的指向来实现。 从引用中提取信息: - [^1]:重定向的本质是改变文件描述符的指向。 - [^2]:文件操作原理涉及文件描述符。 - [^3]:示例展示了如何重定向stdout和stderr。 - [^4]:文件描述符是进程管理打开文件的关键。 - [^5]:虽然主要是cp命令的示例,但可以忽略,因为它不直接相关。 回答结构: 1. **定义重定向**:解释什么是重定向。 2. **原理**:详细说明基于文件描述符的机制。 3. **示例**:使用引用中的例子来阐述。 4. **引用**:在相关段落末尾添加引用标识。 5. **生成相关问题**:在结尾添加相关问题。 由于有数学表达式的要求,但重定向涉及IO,可能没有数学公式。如果有,比如在解释文件描述符时,但通常是整数,所以可能不需要数学格式。如果有概率或方程,但这里没有,所以我可以忽略。 回答大纲: - 开头:直接定义重定向。 - 原理部分: - 文件描述符的概念。 - 标准输入、输出、错误。 - 重定向如何改变文件描述符。 - 示例:从引用[^3]中取例子。 - 结尾:总结并生成相关问题。 生成相关问题: - 基于主题,如重定向的优化、应用场景等。 - 例如: 1. 如何重定向标准错误? 2. 重定向和管道有什么区别? 3. 在脚本中如何使用重定向? 确保回答清晰、逐步: - 步骤1: 定义 - 步骤2: 原理 - 步骤3: 示例 - 步骤4: 总结</think>### Linux基础IO重定向的定义及原理 在Linux系统中,重定向是一种基础IO操作,它允许用户改变命令的输入/输出源或目的地。下面我将逐步解释其定义、原理及相关机制,确保回答基于可靠的Linux内核机制和标准实践。 #### 1. **重定向的定义** - **基本概念**:重定向是指将命令的标准输入(stdin)、标准输出(stdout)或标准错误(stderr)从默认设备(如终端)重新定向到其他位置,例如文件或另一个命令。例如: - 输出重定向:将命令的输出从屏幕重定向到文件(如 `ls > file.txt`)。 - 输入重定向:从文件读取输入而非键盘(如 `sort < input.txt`)。 - **核心目的**:提升灵活性和效率,例如保存日志、批量处理数据或错误隔离[^1][^2]。 #### 2. **重定向的原理** 重定向的底层原理基于Linux的**文件描述符**机制和**进程管理**。以下是关键步骤的分解: - **步骤1: 文件描述符的基础** 每个进程启动时,内核会分配三个默认文件描述符(file descriptors): - `0`:标准输入(stdin),对应键盘输入。 - `1`:标准输出(stdout),对应屏幕输出。 - `2`:标准错误(stderr),对应屏幕错误输出。 文件描述符是进程访问打开文件的索引,内核通过它管理文件操作[^4][^2]。 - **步骤2: 重定向的实现机制** 当用户执行重定向命令(如 `command > file`),内核会: 1. **创建或打开目标文件**:例如,打开 `file` 用于写入。 2. **复制文件描述符**:使用系统调用(如 `dup2`)将目标文件的描述符复制到默认描述符的位置。例如: - `command > file` 将 `stdout`(描述符1)指向 `file` 的文件句柄。 - `command 2> error.log` 将 `stderr`(描述符2)指向 `error.log`。 3. **替换指向**:进程的默认描述符被替换为新的指向,所有输出或输入操作自动重定向到新位置。 这一过程本质是**修改进程的文件描述符表**,而非改变命令本身[^1][^3][^4]。 - **步骤3: 底层原理图解** 以 `ls > output.txt` 为例: - 初始状态:`stdout` 描述符1指向终端设备文件。 - 重定向后:内核将描述符1重定向到 `output.txt` 的文件句柄。 - 结果:`ls` 的输出写入文件而非屏幕。 这一机制依赖于Linux的**虚拟文件系统(VFS)**,确保所有IO操作统一处理[^2][^4]。 - **数学表示(如适用)** 在描述符管理中,文件描述符的复制可抽象为: $$ \text{dup2}(old\_fd, new\_fd) $$ 其中,`old_fd` 是目标文件的描述符,`new_fd` 是标准描述符(如1或2)。该调用将 `new_fd` 指向 `old_fd` 的文件对象,实现重定向[^1][^4]。 #### 3. **示例说明** 引用中的代码示例展示了重定向的常见问题: - 默认重定向仅影响 `stdout`(描述符1),如 `./a.out > stdout.txt`。 - 如果需要重定向 `stderr`(描述符2),必须显式指定: ```bash ./a.out 1> stdout.txt 2> stderr.txt ``` 这确保了错误输出独立保存,避免混合输出[^3]。 此示例验证了原理:内核通过描述符编号区分IO流。 #### 4. **总结** 重定向的本质是**通过修改进程的文件描述符表来改变IO流的指向**。它不改变命令的行为,而是改变其输入/输出的目的地。理解这一点有助于诊断IO问题(如输出未重定向)或优化脚本设计[^1][^2][^4]。重定向广泛应用于日志记录、数据管道和错误处理中。 ### 相关问题 1. 如何同时重定向标准输出和标准错误到同一个文件? 2. 重定向和管道(pipe)在原理上有何区别? 3. 在Shell脚本中,如何实现输入重定向以批量处理数据?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值