`

玩转Linux文件描述符和重定向

 
阅读更多

本文介绍linux中文件描述符与重定向的相关知识,文件描述符是与文件输入、输出相关联的整数,它们用来跟踪已打开的文件。有需要的朋友参考下。
原文出处:http://www.jbxue.com/article/14035.html

linux下的文件描述符是与文件输入、输出相关联的整数。它们用来跟踪已打开的文件。
最常见的文件描述符是stdin、stdout和stderr.我们可以将某个文件描述符的内容重定向到另一个文件描述符中。

下面给出一些对文件描述符进行操作和重定向的例子。

1.5.1 预备知识

我们在编写脚本时会频繁使用标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。

通过内容过滤将输出重定向到文件是我们从事的基础任务之一。

当命令输出文本时,这些输出文本有可能是错误信息,也可能是正常的(非错误的)输出信息。
单靠查看输出的文本本身,  我们无法区分哪些是正常的输出文本,哪些是错误文本。不过,我们可以通过文件描述符来解决这个问题,将那些与特定描述符关联的文本提取出来。
文件描述符是与一个打开的文件或数据流相关联的整数。文件描述符0、1以及2是系统预留的。
0——stdin(标准输入)
1——stdout(标准输出)
2——stderr(标准错误)

1.5.2  实战演练

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

 

复制代码
代码如下:

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

 

这种方法通过截取文件的方式,将输出文本存储到文件temp.txt中,也就是说在把echo命令的输出写入文件之前,temp.txt中的内容首先会被清空。
接下来,再看另一个例子:
 

复制代码
代码如下:

$echo "this is sample text 2" >>temp.txt

 

这种方法会将文本追加到目标文件中。
>和>>并不相同。尽管这两个操作符都可以将文本重定向到文件,但是前者会先清空文件,再写入内容;而后者会将内容追加到现有文件的尾部。
可以用下面的方法查看文件内容:

 

复制代码
代码如下:

$cat temp.txt
this is sample text 1
this is sample text 2

 

linux操作系统中,当使用重定向操作符时,重定向的内容不会出现在终端,而是直接被导入文件。重定向操作符默认使用标准输出。如果想使用特定的文件描述符,你必须将描述符置于操作符之前。

>等同于1>;对于>>来说,情况也类似(即>>等同于1>>)。
来看看什么是标准错误以及如何对它重定向。当命令输出错误信息时,stderr信息就会被打印出来。考虑下面的例子:
 

复制代码
代码如下:

$ Is + 
Is:cannot access +:No such file or directory 

 

这里,+是一个非法参数,因些将返回错误信息。
[ 成功和不成功的命令
   当一个命令发生错误并退回时,它会返回一个非0的退出状态;而当命令成功完成后,它会返回数字0。退出状态可以从特殊变量$? 中获得(在命令执行语句之后立刻运行echo$?,就可以打印出退出状态)。]

将stderr文本打印到屏幕上,而不是文件中。

 

复制代码
代码如下:

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

 

然而在下面的命令中,stdout没有任何输出,因为错误已经重定向到out.txt中去了。

 

复制代码
代码如下:

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

 

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

 

复制代码
代码如下:

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

 

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

 

复制代码
代码如下:

$ cmd 2>&1 output.txt

 

或者采用下列方法:

 

复制代码
代码如下:

$ cmd&> output.txt

 

有时候,在输出中可能包含一些不必要的信息(比如除错信息)。如果你不想让终端中充斥着有关stderr的繁枝末节,那么你可以将stderr的输出重定向到/dev/null, 保证一切都会被清除得干干净净。假设我们有三个文件,分别是a1、a2、a3。但是普通用户对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

 

观察下面的代码:

 

复制代码
代码如下:

$ some_command 2>/dev/null

 

本节是 玩转Linux文件描述符和重定向 第二页的内容,欢迎大家继续阅读。

在这个示例中,来自stderr的输出被丢到文件/dev/null中。/dev/null是一个特殊的设备文件,这个文件接收到的任何数据都会被丢弃。

因此,null设备通常也被为位桶(bit bucket)或黑洞。
当对stderr或stdout进行重定向时,重定向的文本将传入文件。

因为文本已经被重定向到文件中,也就没剩下什么东西可以通过管道(|)传给接下来的命令,而这些命令是通过stdin来接收文本的。
但是有一个巧妙的方法可以一方面将数据重定向到文件,另一方面还可以提供一些重定向数据的副本作为后续命令的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
1 a1
2 a1 

 

查看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依次类推,或者简简单单地用command FILE。
我们可以使用stdin作为命令参数。只需要将-作为命令的文件名参数即可:

 

复制代码
代码如下:

$ cmd1 |cmd2 |cmd - 

 

例如:

 

复制代码
代码如下:

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

 

或者我们也可以将/dev/stdin作为输出文件名来使用stdin。
类似的,使用/dev/stderr代表标准错误,/dev/stdout代表标准输出。这些特殊的设备文件分别对应stdin、stderr和stdout。

补充内容:
从stdin读取输入的命令能以多种方式接收数据。另外,还可以用cat和管道来制定我们自己的文件描述符,例如:

 

复制代码
代码如下:

$ cat file | cmd
$ cmd1 | cmd2 

 

1.将文件重定向到命令
借助重定向,我们可以像使用stdin那样从文件中读取数据:

 

复制代码
代码如下:

$ cmd <file 

 

2.重定向脚本内部的文本块
有时候,需要对文本块(多行文本)像标准输入一样进行重定向。考虑一个特殊情况:源文本就位于shell脚本中。

来看下面这段shell脚本吧,向log文件中写入头部数据,可以按照下面的方法完成:

 

复制代码
代码如下:

#!/bin/bash
cat <<EOF>log.txt
LOG FILE HEADER
This is a test log file
Function:System statistics
EOF 

 

在cat <<EOF>log.txt与下一个EOF行之间的所有文本行都会被当做stdin数据。log.txt文件的内容打印如下:

 

复制代码
代码如下:

$ cat log.txt
LOG FILE HEADER
This is a test log file
Function:System statistics
分享到:
评论

相关推荐

    Linux管道符与重定向.pdf

    Linux 管道符与重定向是 Linux 系统中两种重要的机制,分别用于控制命令的输入/输出和重定向输出到文件。Linux 命令的输入通常来自键盘,但也可以来自文件,而输出通常到监视器或屏幕上。Linux 计算环境使用重定向...

    Linux下重定向详解

    - **I/O重定向**:通常与文件描述符(File Descriptor, FD)有关,shell中通常包含10个文件描述符,编号为0至9。 - **常用文件描述符**: - 0 (stdin, 标准输入):默认与键盘关联,用于接收用户的输入。 - 1 (stdout...

    linux中的重定向.pdf

    总之,Linux中的重定向是实现文件、设备和命令之间数据流管理的工具,它通过特殊的文件描述符和重定向操作符实现,使得用户可以灵活地控制数据流向。通过了解和掌握这些重定向机制,可以极大提升工作效率,有效地...

    嵌入式开发教程之linux进程与它的文件描述符--千锋培训

    【嵌入式开发教程之Linux进程与它的文件描述符】是一个深入探讨Linux系统中进程管理和文件操作的主题。在这个教程中,我们将重点解析五个关键部分: 一、概述:在Linux操作系统中,每个进程都有一个独立的文件描述...

    Linux标准输入、输出和重定向

    1. **标准输入(Standard Input, stdin)**:文件描述符为0,通常与终端的键盘关联,用来接收用户的输入数据。 2. **标准输出(Standard Output, stdout)**:文件描述符为1,通常与终端的屏幕关联,用来展示进程...

    用来操作文件描述符的一些特性

    在Linux系统中,`fcntl()`函数就是一个典型的例子,它允许程序员通过不同的`cmd`参数来控制文件描述符的行为,如`F_GETFL`获取文件标志、`F_SETFL`设置文件标志等。 #### 特性示例:网络套接字操作 在上述部分提供...

    Linux运维之管道符、重定向与环境变量(MD格式)

    Linux运维之管道符、重定向与环境变量(MD格式)

    文件描述符1

    在计算机科学,特别是操作系统领域,文件描述符(File Descriptor)是一个关键的概念,特别是在Linux和类Unix系统中。文件描述符是进程与操作系统交互的一种方式,主要用于读写文件、网络通信等I/O操作。以下是关于...

    文件描述符本质1

    标题中的“文件描述符本质1”指的是在操作系统中,文件描述符是访问文件或设备的基本方式,它是进程间通信和I/O操作的核心概念。在这个话题下,我们将深入探讨文件描述符的概念、工作原理以及在实际编程中的应用。 ...

    Linux操作之输入输出重定向和管道

    ### Linux操作之输入输出重定向和管道 #### 标准输入输出与错误处理 在Linux或Unix环境下,标准输入(`stdin`)、标准输出(`stdout`)以及标准错误输出(`stderr`)是非常重要的概念。这三个流通常与控制终端关联...

    android进程间socket传递Ashmem的文件描述符

    Socket不仅可以传输数据,还可以通过`sendmsg()`和`recvmsg()`系统调用传递文件描述符,这得益于Linux的`sendfile()`和`splice()`系统调用的扩展。 具体实现步骤如下: 1. **创建Ashmem**:在进程A中,通过` ...

    man手册,管道符和重定向.docx

    在Linux操作系统中,理解和掌握`man`手册、管道符和重定向是提高效率和解决问题的关键技能。下面将详细介绍这三个概念及其应用。 首先,让我们来看看`man`手册。`man`是Linux系统中用于查看命令、系统调用、库函数...

    Linux应用技术:Linux重定向与管道.pptx

    项目3 Linux磁盘文件管理 第三讲 主要内容 Linux操作命令 Linux目录管理 Linux文件管理 拓展:管道和重定向 Linux文件系统 系统及其他命令 vi编辑器 磁盘分区管理 拓展:重定向 输出重定向 功能:将一个命令的输出...

    linux下文件描述符限制问题

    linux下文件描述符最大限制默认最大为1024,通过 [root@localhost ~]# ulimit -n 1024 这个命令可以查看。此值可以修改。 进程的文件描述符,可以通过 [root@localhost ~]# ls -al /proc/13623/fd |wc -l 59 输出...

    Linux实验八:LinuxC-编程-IO-重定向和管道.doc

    在Linux系统中,I/O重定向和管道是两种重要的进程间通信(IPC)方式,它们允许我们改变程序的标准输入、输出和错误流,或者在不同的进程中传递数据。本实验主要涵盖了这两个主题,通过编写和运行C语言程序来实践。 ...

    从以重定向的文件描述符中恢复.sh

    从以重定向的文件描述符中恢复

    linux中的重定向问题

    同时重定向标准输出和标准错误输出到同一个文件。 #### 知识点三:通过`system()`函数实现重定向 在C语言中,可以使用`system()`函数执行shell命令,从而实现重定向。例如: ```c #include int main() { system...

    linux重定向和管道符

    在Linux操作系统中,重定向和管道符是两个非常重要的概念,它们极大地增强了命令行界面的灵活性和功能性。让我们深入探讨这两个主题。 **一、标准输入输出** 在Linux中,每个命令或程序都有三个标准流:标准输入...

    Linux重定向_All.pdf

    Linux重定向是通过特殊的文件描述符来控制输入输出流的机制。在Linux系统中,重定向允许用户将命令的输出从默认位置(屏幕)重定向到文件中,或者将文件作为命令输入的来源,从而实现对输入输出流的精确控制。 1. ...

    Linux进程间传递文件描术符事例代码

    文件描述符是Linux系统中对打开文件的一种抽象表示,每个进程都有一个文件描述符表,用于管理其打开的文件或套接字等资源。本示例代码将探讨如何在两个进程之间传递文件描述符,以实现数据共享。 首先,我们来看`...

Global site tag (gtag.js) - Google Analytics