1、概念

在解释什么是重定向之前,先来说说什么是文件描述符

Linux 文件描述符

文件描述符可以理解为 Linux 系统为文件分配的一个数字,范围是 0-3 ,用户也可以自定义文件描述符,但是自定文件描述符不在这里的讨论范围



文件描述符(file descriptor)

名称 类型 文件描述符 操作
标准输入 standard input 0 <,<<
标准输出 standard output 1 >,>>
标准错误输出 standard error output 2 2>,2>>

文件描述符的存储位置位于 /proc/self/fd ,文件描述符是通过一系列软链接指向的默认输出设备,这里我们的默认设备就是模拟终端

模拟终端的文件可以使用命令 tty 来查看

[divent@bash]$ ls -al /proc/self/fd
total 0
lrwx------. 1 divent divent 64 Aug 15 14:09 0 -> /dev/pts/0
lrwx------. 1 divent divent 64 Aug 15 14:09 1 -> /dev/pts/0
lrwx------. 1 divent divent 64 Aug 15 14:09 2 -> /dev/pts/0

对于一条 Linux 的命令执行的过程如下

  1. 用户开始从键盘(键盘在 Linux 上属于文件)输入数据,也就是系统从文件中读取数据的时候
  2. shell 将接受到的数据(标准输入)传递给相应的命令开始执行
  3. (yes)执行成功后,即可获得标准正确输出。(no)执行失败后,获得标准错误输出
  4. 在默认情况下,标准正确输出的结果与标准错误输出的缺省输出都为当前用户执行的终端

一个命令执行以前,会准备好所有的输入输出,默认分别绑定 stdin(0),stdout(1),stderr(2)。如果在准备命令的时候出现错误,那么这个命令将不会执行


2、输出重定向

格式

command [OPTION]{>,>>} [File]
option:
1 standard output(default)
2 standard error output
& all output

> 为覆盖输出,>>为追加输出

示例

#假设当前文件夹有文件 test2
[divent@bash]$ ls test test2
ls: cannot access test: No such file or directory
test2

这里可以看到同时拥有的标准输出与标准错误输出都显示在了屏幕上

现在我们要将输出写入到文件中

#假设已经有文件 test2 , test3
[divent@bash]$ ls test test2 > test3
ls: cannot access test: No such file or directory
[divent@bash]$ cat test3
test2

因为这里的文件只默认接受了标准输出,所以标准错误输出就输出到了终端上

我们也可以将标准错误输出写入到文件

#假设已经有文件 test2 , stderr
[divent@bash]$ ls test test2 2> stderr
test2
[divent@bash]$ cat stderr
ls: cannot access test: No such file or directory

这里获得的结果就和刚刚的结果正好相反

我们也可以将标准输出与标准错误输出都重定向到不同的文件

#假设已经有文件 test2 , stdout , stderr
[divent@bash]$ ls test test2 1> stdout 2>stderr
[divent@bash]$ cat stdout
test2
[divent@bash]$ cat stderr
ls: cannot access test: No such file or directory

这里我们就将两个不同的输出输出到了指定的文件中

我们也可以将两个输出同时输出到同一个文件中

#假设已经有文件 test2 , test3
[divent@bash]$ ls test test2 &> test3
[divent@bash]$ cat test3
ls: cannot access test: No such file or directory
test2

这里就使用 & 将两种输出同时输出到了同一个文件

我们也可以只接受某一种输出,而将其他的输出导向到其他地方

#假设已经有文件 test2
[divent@bash]$ ls test test2 2>&-
test2
[divent@bash]$ ls test test2 2>/dev/null
test2
# &- 意义为关闭这个输出,/dev/null 是 linux 的黑洞设备

注意

  • shell遇到 > 操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件。不存在直接创建。 无论左边命令执行是否成功。右边文件都会变为空。
  • >> 操作符,判断右边文件是否存在,如果不存在,先创建。以添加方式打开文件,会分配一个文件描述符[不特别指定,默认为1]然后,与左边对应的输出绑定。
  • 一条命令在执行前,先会检查输出是否正确,如果输出设备错误,将不会进行命令执行

3、输入重定向

格式

command {<} [File] {<<} [Word]

这里的 <<< 意义不是类似于输出重定向的操作符,< 是从文件中取出数据到指定的文件中

示例

[divent@bash]$ cat > newfile
123
abc
456
[divent@bash]$cat newfile
123
abc
456
#这里使用 Ctrl + D 可以结束输入,从键盘输入的数据会保存存到 newfile 文件中

cat 命令直接使用的话可以直接接收键盘的输入

现在来尝试从文件中输入

#这里的示例我们使用刚才创建的 test3 文件
[divent@bash]$ cat test3
ls: cannot access test: No such file or directory
test2
[divent@bash]$ cat > newfile < test3
[divent@bash]$ cat newfile
ls: cannot access test: No such file or directory
test2

这里的先将文件中的数据提取到了命令 cat 中 ,然后由 cat 写入到 newfile


4、自定义输入输出设备

解释

除了使用系统给你定义的文件描述符以外,用户还可以自己自定义文件描述符,首先使用 ulimit -n 来查看文件描述符的上限,然后使用命令 exec 来为一个文件添加文件描述符

示例

#首先查看一下现在已经被占用的文件描述符
[divent@bash]$ ls /proc/self/fd
0 1 2 3 #这个时候我们可以使用 exec 命令来为一个文件赋予一个文件描述符
[divent@bash]$ touch /tmp/test && exec 5>/tmp/test #然后我们再查看文件描述符 5
[divent@bash]$ ls -al /proc/self/fd/5
l-wx------. 1 divent divent 64 Aug 15 14:54 /proc/self/fd/5 -> /tmp/test #现在我们使用自己自定义的文件描述符来重定向输出
[divent@bash]$ ls -l /etc >&5 #然后我们再来查看文件中的数据, 因为文件中有数据,这里就只取出前 5 行作为示例
[divent@bash]$ head -n 5 /tmp/test
total 1936
drwxr-xr-x. 3 root root 4096 Jun 10 22:12 abrt
-rw-r--r--. 1 root root 16 Jun 9 16:56 adjtime
-rw-r--r--. 1 root root 1518 Feb 22 22:11 aliases
drwxr-xr-x. 2 root root 4096 Jun 10 22:11 alsa #我们也可以使用 exec 来将文件的默认输出指向文件
[divent@bash]$ exec 1>&5
[divent@bash]$ ls -l /etc
#这个时候就会发现没有输出了,已经输出内容已经到了 /tmp/test 中了 #如果想要恢复输出,将默认输出重新指向当前 /dev/pts/0 即可
[divent@bash]$ exec 1>/dev/pts/0 #关闭文件描述符
[divent@bash]$ exec 5>&- #最后我们查看一下
[divent@bash]$ ls /proc/self/fd
0 1 2 3

最后说两句

  • 如果不是很好理解的话,一定要贯彻 Linux 一切皆文件的理念,文件描述符最终也是指向的是文件
  • 使用自己自定义的描述符可以简化一些备份之类的任务
  • 在 shell 脚本中,输入输出重定向是经常使用的

Linux 输入输出(I/O)重定向的更多相关文章

  1. 全面理解Linux输入输出重定向

    全面理解Linux输入输出重定向 本教程通过视频方式讲解shell操作,理解感念,教程通俗易懂,比起看一大堆文档要舒服的多.本次教程主要讲解  Linux Shell 中支持输入输出重定向,用符号&l ...

  2. Linux输入输出重定向和文件查找值grep命令

    Linux输入输出重定向和文件查找值grep命令 一.文件描述符Linux 的shell命令,可以通过文件描述符来引用一些文件,通常使用到的文件描述符为0,1,2.Linux系统实际上有12个文件描述 ...

  3. [转帖]Linux教程(12)- linux输入输出重定向

    Linux教程(12)- linux输入输出重定向 2018-08-21 22:57:02 钱婷婷 阅读数 49更多 分类专栏: Linux教程与操作 Linux教程与使用   版权声明:本文为博主原 ...

  4. Linux 输入输出重定向, &>file, 2>&1, 1>&2

    Linux 输入输出重定向, &>file, 2>&1, 1>&2 一.1和2在Linux中代表什么 1.1 输出重定向 1.2 输入重定向 1.3 绑定重定 ...

  5. Linux脚本执行过程重定向

    Linux脚本执行过程重定向 一.bash调试脚本,并将执行过程重定向到指定文件 bash –x  shell.sh 2>&1 | tee shell.log

  6. linux 将debug信息重定向到LCD(屏幕)

    /*********************************************************************** * linux 将debug信息重定向到LCD(屏幕) ...

  7. Linux文件查看及重定向

    Linux文件查看及重定向   实验目标: 通过本实验掌握head.tail.cat.more.less等文件查看命令的使用,理解重定向的概念,掌握两种重定向方法的使用. 实验步骤: 1.通过head ...

  8. linux输入输出重定向

    http://www.cnblogs.com/chengmo/archive/2010/10/20/1855805.html 在Linux下,当一个用户进程被创建的时候,系统会自动为该进程创建三个数据 ...

  9. [100]linux输入输出重定向

    一目了然版本: &号含义: 参考 参考:非常经典,值得一看,我是在linux爱好者公众号里发现的. 下面是我自己的一些总结. linux的命令数据流 在Linux下,当一个用户进程被创建的时候 ...

随机推荐

  1. Process子类

    创建新的进程还能够使用类的方式,可以自定义一个类,继承Process类,每次实例化这个类的时候,就等同于实例化一个进程对象,请看下面的实例: from multiprocessing import P ...

  2. Managing Images on smartos

    SmartOS依赖images.images是包含在创建新zone或虚拟机时使用的磁盘或文件系统映像和元数据的模板. images使用imgadm工具进行管理. 使用此工具,您可以: 查看和下载在公共 ...

  3. zabbix出现中文不能选的情况

    像这里一样,有些选项是选不了的,这个时候我们要做的第一步就是,找到这个配置文件. 如果不知道在哪里的话可以用find命令查找. sudo find / -name locales.inc.php 找到 ...

  4. mysql 数值与字符类型 长度梳理

    上述表格中的数值类型都是定长的,也就是说,无论你存的数值是多少,多大或者多小,占用的存储字节大小都是固定的.例如,设置int(1),虽然M值是1个字符,但是它所占用的空间大小永远都是4个字节的大小,换 ...

  5. do you\have you\are you

    如果想问对方动作方面的 就用do you 例如 你知道吗? do you konw 如果想问对方是不是什么 就用are you 例如 你是一名教师吗 are you a teacher ? 如果想问对 ...

  6. Mybatis中传入时间值

    <if test="search_content2 != null and search_content2 != ''"> AND add_time <![CDA ...

  7. ReactNative手势解锁(react-native-ok-gesture-password)

    在大前端的趋势之下,我也慢慢开始从事React Native相关的开发.但是奈何React Native生态相对于Android来说还是太小了.许多开源的库早早就已经不再维护.之前项目中需要用到手势解 ...

  8. 可以foreach的 必须继承IEnumable 接口才行

    只要是继承IEnumable 都可以用foreach遍历

  9. java并发:CAS算法和ABA问题

    CAS算法是硬件对于并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令. CAS用于管理对共享数据的并发访问. java的并发包中,AQS.原子操作类等都是基于CAS实现的. CAS 是一种 ...

  10. phpStudy4——前端页面使用Ajax请求并解析php返回的json数据

    项目需求: 在html页面显示所有用户列表信息. 需求分析: 1. html页面使用ajax向后端php请求用户数据 2. php脚本查询数据库,并将查询后的结果以json格式返回前端html页面 3 ...