Overview

了解Linux怎样处理输入和输出是非常重要的。一旦我们了解其原理以后,我们就可以正确熟练地使用脚本把内容输出到正确的位置。同样我们也可以更好地理解输入重定向和输出重定向。

Linux标准文件描述符

文件描述符 缩写 描述
0 STDIN 标准输入
1 STDOUT 标准输出
2 STDERR 标准错误输出

Linux系统将所有设备都当作文件来处理,而Linux用文件描述符来标识每个文件对象。其实我们可以想象我们电脑的显示器和键盘在Linux系统中都被看作是文件,而它们都有相应的文件描述符与之对应。

其实我们与计算机之间的交互是我可以输入一些指令之后它给我一些输出。那么我们可以把上面表格中的文件描述符0理解为我和计算机交互时的输入,而这个输入默认是指向键盘的; 文件描述符1理解为我和计算机交互时的输出,而这个输出默认是指向显示器的;文件描述符2理解为我和计算机交互时,计算机出现错误时的输出,而这个输出默认是和文件描述符1指向一个位置;

就像我上面说的那样,既然它们是默认的,我就可以更改它们。下面的命令就是把标准输出的位置改到xlinsist文件中:

exec 1> xlinsist
  • 1

这回如果我输入ls -al 或者ps命令,我们的终端将不会显示任何东西。现在,我们可以新开一个终端查看xlinsist这个文件中是否有上面两个命令所显示的内容。注意:你必须新开一个终端。

同样的道理,我们也可以改变标准输入的位置。首先,我们先看看没改变的样子:

vincent@geek:~/test$ read user
xlinsist
vincent@geek:~/test$ echo $user
xlinsist
vincent@geek:~/test$
  • 1
  • 2
  • 3
  • 4
  • 5

也就是我们从键盘输入把xlinsist读入到user变量。这个read需要我输入。现在,我要改变标准输入的默认位置:

#我只是把当前的标准输出重定向到test文件中
vincent@geek:~/test$ echo 'xlinsist' 1> test
vincent@geek:~/test$ cat test
xlinsist
#我只是把当前的标准输入重定向到test文件中
vincent@geek:~/test$ read user 0< test
vincent@geek:~/test$ echo $user
xlinsist
vincent@geek:~/test$
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

从上面的read命令中可以看作,我并没有被要求输入什么。

标准错误输出和标准输出的区别是,它在命令出错情况下的输出。这没有什么太大的不同,我们也可以把它的输出修改到任何我们想要的位置。只不过我们需要把上面标准输出的1改成2,命令如下:

exec 2> xlinsist
  • 1

当然,除了0, 1,2以外,我们可以分配自己的文件描述符。看下面的例子:

vincent@geek:~/test$ exec 6>test
vincent@geek:~/test$ echo 'i love linux shell!!!' 1>&6
vincent@geek:~/test$ cat test
i love linux shell!!!
  • 1
  • 2
  • 3
  • 4

上面的命令很有意思:我首先把文件描述符6指向test文件。因为不像描述符1,所有的输出都会自然找它,然后看它是定向到显示器还是某个文件。所以当我们想找描述符6的时候我们要用&来引用它。其实我们可以把文件描述符想像成一个文件的引用,它可以指向任何一个文件(包括显示器),指向的过程就是我们修改默认位置的过程。而用&符号来找到它指向的目标文件,从而向其写入数据。

如果你真正了解了上面的原理后,我们就可以随便玩什么输入重定向啊、输出重定向啊,那都是小case。现在让我们来个更加复杂的例子吧,来帮你们整理一下思路,脚本如下:

exec 3>&1
exec 1>test
echo "这句话被存到test文件中"
echo "还有这句"
exec 1>&3
echo "这句话输出到显示器"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们来一步一步理解上面的命令:首先文件描述符1默认指向的是显示器,用&来找到文件描述符1指向的目标文件,也就是显示器。因此文件描述符3也指向了显示器。然后,我们修改了文件描述符1指向的文件到test文件。接着两个echo命令的输出会自然去找文件描述符1,然后它看到文件描述符1指向的是test文件,所以它会把输出写到test文件中。最后,我们用&来找到文件描述符3指向的目标文件,也就是显示器,然后我们修改了文件描述符1指向的文件到显示器。因此,最后一个echo命令会自然的找文件描述符1然后输出到显示器上。

整个过程就是这样的,只要你理解了它们的原理,以后无论在脚本中怎样处理重定向的你都不会感觉到迷茫了。下面我将介绍一些与文件描述符相关的一些shell命令,这可以让你如虎添翼。

文件描述符相关的一些shell命令

lsof -a -p $$ -d 0,1,2

#下面为这个命令的输出
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 22609 vincent 0u CHR 136,13 0t0 16 /dev/pts/13
bash 22609 vincent 1u CHR 136,13 0t0 16 /dev/pts/13
bash 22609 vincent 2u CHR 136,13 0t0 16 /dev/pts/13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

下图是上面各项的含义

现在我用下面命令修改其标准错误输出:

vincent@geek:~/test$ exec 1> test
vincent@geek:~/test$ lsof -a -p $$ -d 0,1,2 #新开一个终端,查看test文件,输出如下
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 23061 vincent 0u CHR 136,20 0t0 23 /dev/pts/20
bash 23061 vincent 1w REG 8,2 0 525789 /home/vincent/test/test
bash 23061 vincent 2u CHR 136,20 0t0 23 /dev/pts/20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

/dev/null文件,这是一个很特殊的文件,你写入的任何东西都会清空。大家可以向里面写入数据试试效果。

  1. 我们可以把标准错误输出重定向到/dev/null,从而丢掉不想保存的错误信息
  2. 我们可以快速移除现有文件的数据而不用先删除文件在创建。命令如下:
cat /dev/null > test
  • 1

Linux使用/tmp目录来存放不需要一直保留的文件,大多数Linux系统会在启动时自动删除/tmp目录中所有的文件。

下面的命令可供使用:

# 文档说文件的末尾必须至少包含3个'X',这个是在当前目录创建的
mktemp test.XXX
# 这个是在/tmp目录创建的
mktemp -t test.XXXXX
# 创建目录,在当前目录
mktemp -d test.XXXXX
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

tee命令 – 从标准输入读取,写到标准输出和文件。

# 把date产生的输出写到标准输出和文件
date | tee test
# 追加数据
date | tee -a test
  • 1
  • 2
  • 3
  • 4

管道和重定向之间的区别

管道是把一个程序的输出作为另一个程序的输入。 

重定向是把输出定向到文件或者标准流。

这有2个非常详细的参考资料:

1、http://askubuntu.com/questions/172982/what-is-the-difference-between-redirection-and-pipe

2、http://ryanstutorials.net/linuxtutorial/piping.php

最好是先看第二个链接

转自:http://blog.csdn.net/xlinsist/article/details/51147212

Linux 文件描述符详解的更多相关文章

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

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

  2. Linux 文件/目录操作详解

    目录 Linux 文件/目录操作详解 初识Linux 一.文件/目录显示命令 ls 二.目录创建命令 mkdir 三.目录转移命令 cd 四.当前目录显示命令 pwd 五.文件处理命令 rmdir 六 ...

  3. [转帖]linux文件描述符文件/etc/security/limits.conf

    linux文件描述符文件/etc/security/limits.conf https://blog.csdn.net/fanren224/article/details/79971359 需要多学习 ...

  4. linux文件描述符、软硬连接、输入输出重定向

    引用链接:https://blog.csdn.net/qq769651718/article/details/79459346 文件描述符的作用: 文件描述符是linux操作系统中特有的概念.其相当于 ...

  5. Linux文件描述符与打开文件之间的区别(转载)

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239   1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为: ...

  6. linux文件描述符--转载

    转自:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录 ...

  7. [性能分析]linux文件描述符(转)

    1.什么是文件和文件描述符 Linux中文件可以分为4种:普通文件.目录文件.链接文件和设备文件.1.普通文件是用户日常使用最多的文件,包括文本文件.shell脚本.二进制的可执行和各种类型的数据.l ...

  8. linux 文件描述符

    文件描述符是什么?和文件句柄有啥区别?文件描述符是linux/unix操作系统中特有的概念.相当于windows系统中的文件句柄.一个意思不同叫法.Linux系统中, 每当进程打开一个文件时,系统就为 ...

  9. [性能分析]linux文件描述符

    1.什么是文件和文件描述符 Linux中文件可以分为4种:普通文件.目录文件.链接文件和设备文件.1.普通文件是用户日常使用最多的文件,包括文本文件.shell脚本.二进制的可执行和各种类型的数据.l ...

随机推荐

  1. ajax请求-IE缓存处理

    IE浏览器下使用GET发送请求时,如果两次请求的地址和参数相同,在不刷新页面的情况下,浏览器会缓存第一次的请求的内容,服务端更新后浏览器仍然显示第一次的内容 如在当前页面用户登录,在未登录的情况下,服 ...

  2. flowable ContentEngine和ContentEngineConfiguration的关系

    一.CommandExecutor ContentEngineConfiguration继承自 AbstractEngineConfiguration. 在 AbstractEngineConfigu ...

  3. [置顶] 【机器学习PAI实践七】文本分析算法实现新闻自动分类

    一.背景 新闻分类是文本挖掘领域较为常见的场景.目前很多媒体或是内容生产商对于新闻这种文本的分类常常采用人肉打标的方式,消耗了大量的人力资源.本文尝试通过智能的文本挖掘算法对于新闻文本进行分类.无需任 ...

  4. 根据显示器的分辨率,加载不同CSS样式表

    <link rel="stylesheet" type="text/css" id="css"><script langu ...

  5. python(十二):网络编程之ISO/OSI模型

    互联网(Internet)是依据操作系统,在计算机硬件的基础上建立起的通讯机制.它依赖于TCP/IP协议栈. 一.ISO/OSI模型 1.ISO七层模型与OSI五层模型 它们将计算机抽象成了具有层级关 ...

  6. python3 scrapy main运行调式

    from scrapy.cmdline import execute import sys import os sys.path.append(os.path.dirname(os.path.absp ...

  7. Cockpit 服务化管理工具

    Cockpit 是红帽开发的网页版图像化服务管理工具,优点是无需中间层,且可以管理多种服务. 根据其项目主站描述,Cockpit 有如下特点: 从易用性考虑设计,方便管理人员使用,而不是仅仅的终端命令 ...

  8. 7个GIF动图帮你瞬间理解三角函数

    7个GIF动图帮你瞬间理解三角函数 蝌蚪五线谱 百家号04-2120:53 图片来源:IMGUR 三角函数是数学中研究三角形的一个分支,专门阐述三角形的角度和对应边的关系. 有趣的是,定义边角关系的三 ...

  9. cacti监控linux主机时iptables阻碍了udp161端口造成无法监控解

    由于在添加linux主机时,有防火墙启用,造成无法监控linux主机,现有两种方法解决无法监控linux主机问题:可以通过在监控主机执行该命令: snmpwalk -c public -v 2c 19 ...

  10. 将 PCB 文件转换为可读的文本

    将 PCB 文件转换为可读的文本 将元件转成列表. 坐标也放到列表中. 以元件号为排序. 使用 json 格式,并格式,方便对比. 元件网络转成单独文件. 特殊说明生成单独文件.