Linux - Shell - Linux 标准 I/O 与 输出重定向

  1. 概述

    1. linux 输入输出流
    2. 入门
  2. 背景

    1. 尝试理解 linux 的 输入输出流
    2. 困扰了我很久, 但是一直没有做 总结
    3. 今天把这个坑填上
  3. 类型

    1. 教程向
  4. 环境

    1. OS
      1. centos7

1. shell 输入输出流

  1. 概述

    1. shell 输入输出流
  2. 场景: 日常使用 shell

    1. 概述

      1. 日常 shell
    2. 场景

      1. 日常使用 shell
        1. 使用模式

          1. 输入命令
          2. 输出结果
        2. 输入

          1. 通常是 键盘输入
        3. 输出

          1. 通常是 直接输出在 终端上

2. 文件描述符

  1. 概述

    1. shell 输入输出的原理
    2. 简单说一说, 方便理解
  2. 机制

    1. 进程 与 数据交互
      1. 进程的启动, 几乎都是为了做一些处理

        1. 基于 输入
        2. 给出 输出
      2. 但是 数据从哪里来, 到哪里去, 这个问题必须先想清楚

        1. 如何管理
        2. 如何描述
  3. 进程的处理: 文件描述符

    1. 位置

      1. 每个 进程 中
      2. 文件描述符表
    2. 文件

      1. linux 可以把很多东西, 都视为文件
        1. 数据流, 设备, 文件
        2. 这样会方便管理, 方便实现驱动
    3. 机制

      1. 创建时机
        1. 进程 create, open 系统调用的时候
      2. 关联
        1. 描述符关联 文件 的 inode
        2. inode 再关联具体的文件
      3. 其他 - 后话
        1. 文件描述符, 是 进程 内的
        2. 同一个文件, 可能会被多个进程引用
          1. 它对应的文件描述符, 可能一样也可能不一样
        3. 只要能获取 文件描述符, 配置好 读写权限, 就可以配置各种不同类型的 io
    4. 默认

      1. 默认

        1. 为了方便使用, linux 会给新进程, 配置 3 个流
        2. 作为 输入输出的载体
        1. 输入
          1. stdin - 默认对应键盘输入
            1. 编号为 0
        2. 输出
          1. stdout - 默认对应 终端
            1. 编号为 1
          2. stderr - 默认对应 终端
            1. 编号为 2
    5. 问题

      1. 问题
        1. 说了那么多, 方便输入输出, 万一默认的不好使, 怎么办呢?
      2. 解答
        1. 办法当然有啦

3. 重定向

  1. 概述

    1. 简单描述 重定向
  2. 准备

    1. cat

      1. 查看文件的命令
      2. 会将 输入 直接打在 输出 上
    2. 查看文件描述符

      1. 命令

        # pid 怎么来我就不说了
        > ll /proc/<pid>/fd
        

1. 输入重定向

  1. 概述

    1. 输入重定向
  2. 输入

    1. 终端的输入

      1. 键盘
        1. 终端里的命令, 通常是 键盘 打进去的
          1. 粘贴的机制, 我暂时不清楚...
    2. 命令的输入

      1. 参数

        1. 将 文件/设备/流 作为 参数, 传递给 命令
        2. 会 额外增加 新的文件描述符
        3. | xargs
      2. 输入流

        1. 直接使用 stdin
        2. 不会增加新的文件描述符
        3. |
  3. 例子

    # 1. 使用 参数, 这个最常见
    > cat <inputFile>
    
    # 2. 使用 stdin
    ## 输入 cat 命令后, 直接敲 回车
    ## 然后的模式是, 输入一行, 回车一行, 显式一行
    ## ctrl + c 退出
    > cat
    
    # 3. 使用 stdin, 输入多行
    ## EOF 是结束符, 可以换成别的
    ## 输入多行后, 回车, 直接输出多行
    > cat << EOF
    
    # 4. 输入重定向
    ## 使用起来和 1 差不多
    ## 区别是 不会额外使用 新的文件描述符
    > cat < <inputFile>
    

2. 输出重定向

  1. 概述

    1. 输出重定向
  2. 输出

    1. 分类
      1. 标注输出 - stdout
      2. 标准异常 - stderr
  3. 例子

    # 1. 重定向 stdout
    ## 普通
    ## 没有文件就创建, 有就直接覆盖
    > cat <inputFile> > <stdoutFile>
    > cat <inputFile> 1> <stdoutFile>
    > cat <inputFile> &> <stdoutFile>
    ## 追加
    ## 没有文件就创建, 有就继续追加
    > cat <inputFile> >> <stdoutFile>
    > cat <inputFile> 1>> <stdoutFile>
    > cat <inputFile> &>> <stdoutFile>
    
    # 2. 重定向 stderr
    ## 普通
    > cat <notExistFile> 2> <stderrFile>
    ## 追加
    > cat <notExistFile> 2>> <stderrFile>
    
    # 3. 重定向 stdout 和 stderr
    ## 普通
    > cat <inputFile> 1> <stdoutFile> 2> <stderrFile>
    ## 追加
    > cat <inputFile> 1>> <stdoutFile> 2>> <stderrFile>
    ## 当然, 也可以昏庸
    > cat <inputFile> 1> <stdoutFile> 2>> <stderrFile>
    
    # 4. 重定向 stdout 和 stderr 到同一文件
    ## &1 表示 stdout 当前的目标
    ## &2 类似
    > cat <inputFile> 1> <logFile> 2>&1 
    ## 这样也可以, 但是上面的形式, 见的多一些
    > cat <inputFile> 2> <logFile> 1>&2 
    ## 追加模式也可以
    ## 追加模式, 只用 1 追加, 2 那个不用追加
    > cat <inputFile> 1>> <logFile> 2>&1 
    

3. 混合

  1. 概述

    1. 当然你要都混着, 也不是不可以
  2. 例子

    > cat 1><log> 2>&1
    > cat < anaconda-ks.cfg 1>> log 2>&1
    

4. 后续

  1. 文件描述符

    1. 概念
    2. 限制
  2. 后台执行

    1. &
    2. nohup
  3. 疑问: 子 shell 与 文件描述符

    1. 据说 子shell 会继承 父shell 的文件描述符
      1. 简单尝试了一下, 初步结论确实是这样
      2. 问题
        1. 单独重定向 stderr, 会导致 命令行 可以输入, 但无法刷新
        2. 单独重定向 stdout, 命令行 可以输入, 可以刷新, 但是没有结果
        3. 先重定向 stdout, 再重定向 stderr, 同情况1

ps

  1. ref

    1. Linux的文件描述符

      1. 概述
        1. 文件描述符
        2. 前置知识
    2. linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗?

      1. 概述

        1. 一个我对于 文件描述符 的疑问
      2. 结论

        1. 两个进程中分别产生生成两个独立的 fd
        2. 两个进程可以任意对文件进行读写操作,操作系统并不保证写的原子性
        3. 进程可以通过系统调用对文件加锁,从而实现对文件内容的保护
        4. 任何一个进程删除该文件时,另外一个进程不会立即出现读写失败
        5. 两个进程可以分别读取文件的不同部分而不会相互影响
        6. 一个进程对文件长度和内容的修改另外一个进程可以立即感知
    3. What is the use of file descriptor 255 in bash process

      1. 一个问题

    4 What was the point of separating stdout and stderr?

     1. 为何要让 stderr 和 stdout 分开
         1. 设计者
             1. 早期计算机科学家
    
         2. 原因
             1. 早期日志查找, 完全靠人
             2. 找异常相当痛苦
             3. 于是决定, 将 stderr 分离出来
      2. 这里 markdown 解析出了点问题, 格式我是真的调整不好了...
    
    1. 【Linux基础】linux下的stdin,stdout和stderr理解
posted @ 2020-11-23 18:41  轩辕拾銉  阅读(240)  评论(0编辑  收藏  举报