本文介绍linux中文件描述符与重定向的相关知识,文件描述符是与文件输入、输出相关联的整数,它们用来跟踪已打开的文件。有需要的朋友参考下。

原文出处:

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

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

>等同于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起始的所有文件的内容,你可以使用。

设置一些测试文件:

$ 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

本节是 的内容,欢迎大家继续阅读。

在这个示例中,来自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

2.重定向脚本内部的文本块

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

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

#!/bin/bash

cat

LOG FILE HEADER

This is a test log file

Function:System statistics

EOF

在cat

$ cat log.txt

LOG FILE HEADER

This is a test log file

Function:System statistics

玩转linux文件描述符和重定向,玩转Linux文件描述符和重定向相关推荐

  1. 如何理解Linux shell中的“2>1”(将文件描述2(标准错误输出)的内容重定向到文件描述符1(标准输出))(尼玛>符号竟然不支持搜索,害我搜搜不到,只能搜)

    文章目录 前言 有何妙用 如何理解 总结 前言 有时候我们常看到类似这样的脚本调用: ./test.sh > log.txt 2>&1 这里的2>&1是什么意思?该如 ...

  2. 将您重定向的次数过多什么意思_【linux二三轶事】重定向是啥?文件描述符是啥?...

    [前言] 写这篇文章的原因,是因为我在工作中遇到重定向和fd的时候,被这厮折磨的够呛.现在终于战胜了他们,当然要奏一首凯歌,率土同庆啦! 在开启正文之前,我们必须要先明白几个关键点,这对于理解后面的文 ...

  3. ftpclient读取服务器文件能获得文件名文件大小0_理解Linux的文件描述符FD与Inode

    FD 文件描述符 一.概念 Linux 系统中,把一切都看做是文件,当进程打开现有文件或创建新文件时,内核向进程返回一个文件描述符,文件描述符就是内核为了高效管理已被打开的文件所创建的索引,用来指向被 ...

  4. linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗?

    Linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗? 一:结论 1.两个进程中分别产生生成两个独立的fd 2.两个进程可以任意对文件进行读写操作,操作系统并不保证写的原子性 3.进程 ...

  5. linux重定向到某目录文件,linux shell中12 21 1file_path重定向语法详解

    当初在shell中, 看到">&1"和">&2"始终不明白什么意思.经过在网上的搜索得以解惑.其实这是两种输出. 在 shell 程 ...

  6. .gpg 进程 linux,小知识之Linux系统中的最大进程数,最大文件描述,最大线程数...

    今天来了解一下linux里面的一些小知识: (一)Linux系统中最大可以起多少个进程? (1)32位系统中最多可以起32768个进程 (2)64位系统中最多可以起2的22次方(4194304)约42 ...

  7. linux手动生成dump文件权限不足_来玩一玩Linux常见命令~

    写在前面: 小伙伴儿们,大家好!上一篇我们学习了Linux相关部署方面问题: 这次我们一起来玩一玩常见的Linux相关命令,有点意思: 思维导图: 1,命令格式: 我们刚打开FinalShell,可能 ...

  8. 在python中读取文件时如何去除行末的换行符以及在Windows与Linux中的区别

    [时间]2018.11.14 [题目]在python中读取文件时如何去除行末的换行符以及在Windows与Linux中的区别 一.去除换行符 以使用readline进行读取为例: import red ...

  9. linux删除最后一个换行符,如果它是文件中的最后一个字符,如何删除换行符?...

    perl -pe 'chomp if eof' filename >filename2 或者,编辑文件到位: perl -pi -e 'chomp if eof' filename [编者注: ...

最新文章

  1. Linux之 手动释放内存
  2. webrtc 泄漏真实 ip 地址
  3. Google和Baidu常用的搜索技巧--转
  4. jira webhook 事件触发并程序代码调用jenkins接口触发构建操作
  5. MyBatisPlus中通用CRUD的updateById方法
  6. 逻辑综合——施加约束
  7. java中测试计算能力_这 10 道 Java 测试题,据说阿里 P7 的正确率只有 50%
  8. ARM开发步步深入之NandFlash 4KB突围
  9. lnmp 下php升级,lnmp nginx和php升级方法
  10. 互金策略若干问题(全)
  11. Spring-core-ClassUtils类
  12. Java 在Word创建表格
  13. 2021华为杯数学建模D题完整思路
  14. 因代码泄密,苹果将在电脑上使用人脸识别
  15. 第十九届乐博杯机器人科技嘉年华!圆满落幕!
  16. 多云管理平台解决方案
  17. python归一化 增大差异_Python实现描述性统计
  18. 万字长文,分享腾讯面试攻略
  19. 考研英语核心词汇梳理二
  20. C++中virtual(虚函数)的用法

热门文章

  1. linux下删除目录及其子目录下某种类型文件
  2. 为什么QQ能用网络,而浏览器却不能用网络?
  3. y电容如何选型_干式试验变压器选型依据
  4. oracle实验七 答案,Oracle表的常用查询实验(七)
  5. flv 自动播放 html autostart=true,《网页制作之FLV视频播放代码的编写.doc
  6. 用python画风车_python接口自动化()一)(实现一款简单的接口自动化框架)
  7. 用计算机表白我不喜欢你了,隐藏式表白,表白不一定要用“我喜欢你”这几个字...
  8. golang mysql封装_自己封装的golang 操作数据库方法
  9. mysql报错级别_MySQL启动出现几个警告级别错误
  10. linux系统下压缩文件,Linux系统下文件的压缩.打包与解压