zoukankan      html  css  js  c++  java
  • 玩转文件描述符及重定向

    返回主页面

    文件描述符是与文件输入、输出相关联的整数。它们用来跟踪已打开的文件。最常见的文件 描述符是stdinstdoutstderr。我们甚至可以将某个文件描述符的内容重定向到另一个文 件描述符中。下面给出一些对文件描述符进行操作和重定向的例子。

    在编写脚本的时候会频繁使用标准输入(stdin)、标准输出(stdout)和标准错误 (stderr)。通过内容过滤将输出重定向到文件是我们平日里的基本任务之一。当命令输出文本 时,这些输出文本有可能是错误信息,也可能是正常的(非错误的)输出信息。单靠查看输出的

    文本本身,我们没法区分哪些是正常,哪些是错误。不过可以通过文件描述符来解决这个问题,
    将那些与特定描述符关联的文本提取出来。
    

    文件描述符是与某个打开的文件或数据流相关联的整数。文件描述符01以及2是系统预留的。

    0 —— stdin(标准输入)。 1 —— stdout(标准输出)。 2 —— stderr(标准错误)。

    实例

    (1) 将输出文本重定向或保存到一个文件中:

    echo "This is a sample text 1" > temp.txt

    这种方法通过截断文件的方式,将输出文本存储到文件temp.txt中,也就是说在把 echo命令的输出写入文件之前,temp.txt中的内容首先会被清空。

    (2) 将文本追加到目标文件中

    echo "This is sample text 2" >> temp.txt

    >cat temp.txt
    This is sample text 1
    This is sample text 2
    

    (3) 标准错误以及如何对它重定向。当命令输出错误信息时,stderr信息 就会被打印出来。考虑下面的例子:

    $ ls +

    ls: cannot access +: No such file or directory

    这里,+是一个非法参数,因此将返回错误信息。

    -------------------------------------------------------------------------------

    下面的命令会将stderr文本打印到屏幕上,而不是文件中(而且因为并没有stdout 的输出,所以out.txt没有内容):

    $ ls + > out.txt
    ls: cannot access +: No such file or directory

    下面的命令中,我们将stderr重定向到out.txt:

     $ ls + 2> out.txt #正常运行

    可以将stderr单独重定向到一个文件,将stdout重定向到另一个文件:

    $ cmd 2>stderr.txt 1>stdout.txt

    还可以利用下面这个更好的方法将stderr转换成stdout,使得stderrstdout 都被重定向到同一个文件中:

    $ cmd 2>&1 output.txt
    

    或者这样:

    $ cmd &> output.txt
    

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    (4)有时候,在输出中可能包含一些不必要的信息(比如调试信息)。如果你不想让终端 中充斥着有关stderr的繁枝末节,那么你可以将stderr的输出重定向到 /dev/null

    保证一切都会被清除得干干净净。假设我们有3个文件,分别是a1a2a3。但是普 通用户对文件a1没有“读 执行”权限。

    如果需要打印文件名以a起始的所有文件 的内容,可以使用cat命令。设置一些测试文件:

    $ echo a1 > a1
    $ cp a1 a2 ; cp a2 a3;
    $ chmod 000 a1 #清除所有权限

    尽管可以使用通配符(a*)显示所有的文件内容,但是系统会显示一个出错信息, 因为对文件a1没有可读权限。

    $ cat a*
       cat: a1: Permission denied
       a1
       a1
    

    其中,cat: a1: Permission denied属于stderr。我们可以将stderr信息重定向 到一个文件中,而stdout仍然保持不变。考虑如下代码:

    $ cat a* 2> err.txt # stderr被重定向到err.txt a1
    a1

       $ cat err.txt
       cat: a1: Permission denied
    

    观察下面的代码:

       $ cmd 2>/dev/null
    

    当对如果对stderrstdout进行重定向,被重定向的文本会传入文件。因为文本 已经被重定向到文件中,也就没剩下什么东西可以通过管道(|)传给接下来的命令, 而这些命令是通过stdin进行接收的。

    (5)但是有一个方法既可以将数据重定向到文件,还可以提供一份重定向数据的副本作 为后续命令的stdin。这一切都可以使用tee来实现。举个例子:要在终端中打印 stdout,同时将它重定向到一个文件中,那么可以这样使用tee:

       command | tee FILE1 FILE2
    

    在下面的代码中,tee命令接收到来自stdin的数据。它将stdout的一份副本写入 文件out.txt,同时将另一份副本作为后续命令的stdin。命令cat -n将从stdin中接 收到的每一行数据前加上行号并写入stdout:

       $ cat a* | tee out.txt | cat -n
       cat: a1: Permission denied
    

    1a1 2a1

    查看out.txt的内容:

       $ cat out.txt
       a1
       a1
    

    注意,cat: a1: Permission denied 并没有在文件内容中出现。这是因为这些 信息属于stderr,而tee只能从stdin中读取。

    默认情况下,tee命令会将文件覆盖,但它提供了一个-a选项,用于追加内容。例

    如:$ cat a* | tee -a out.txt | cat –n。 带有参数的命令可以写成:command FILE1 FILE2...或者就简单的使用comman FILE

    (7)我们可以使用stdin作为命令参数。只需要将-作为命令的文件名参数即可:

       $ cmd1 | cmd2 | cmd -
    

    例如:

       $ echo who is this | tee -
       who is this
       who is this
    

    也可以将 /dev/stdin作为输出文件名来代替stdin
    类似地,使用 /dev/stderr代表标准错误,/dev/stdout代表标准输出。这些特殊的设备

    文件分别对应stdinstderrstdout

    3. 自定义文件描述符
    文件描述符是一种用于访问文件的抽象指示器(abstract indicator)。存取文件离不开被称为

    “文件描述符”的特殊数字。012分别是stdinstdoutstderr的预留描述符编号。 我们可以使用exec命令创建自己的文件描述符。如果你对用其他编程语言进行文件编程非

    常熟悉,你可能已经注意到了文件打开模式。通常会用到3种模式。

    只读模式。
    截断写入模式。 追加写入模式。

    < 操作符用于从文件中读取至stdin> 操作符用于截断模式的文件写入(数据在目标文件 内容被截断之后写入)。>>操作符用于追加模式的文件写入。(数据被添加到文件的现有内容中, 而且该目标文件中原有的内容不会丢失。)文件描述符可以用以上三种模式中的任意一种来创建。

      创建一个文件描述符进行文件读取:
    

    $ exec 3<input.txt #使用文件描述符3打开并读取文件

    我们可以这样使用它:

    $ echo this is a test line > input.txt
    $ exec 3<input.txt
    

    现在你就可以在命令中使用文件描述符3了。例如: $ cat<&3

    this is a test line
    

    如果要再次读取,我们就不能继续使用文件描述符3了,而是需要用exec重新分配文件描述 符3来进行二次读取

    创建一个文件描述符用于写入(截断模式):

    $ exec 4>output.txt #打开文件进行写入 例如:

        $ exec 4>output.txt
        $ echo newline >&4
        $ cat output.txt
        newline
    

    创建一个文件描述符用于写入(追加模式):

        $ exec 5>>input.txt
    

    例如:

        $ exec 5>>input.txt
        $ echo appended line >&5
        $ cat input.txt
        newline
    
     
  • 相关阅读:
    在Centos 7下编译openwrt+njit-client
    开博随笔
    Chapter 6. Statements
    Chapter 4. Arrays and Pointers
    Chapter 3. Library Types
    Chapter 2.  Variables and Basic Types
    关于stm32不常用的中断,如何添加, 比如timer10 timer11等
    keil 报错 expected an identifier
    案例分析 串口的地不要接到电源上 会烧掉
    案例分析 CAN OPEN 调试记录 进度
  • 原文地址:https://www.cnblogs.com/tianzhiyun/p/9481356.html
Copyright © 2011-2022 走看看