linux shell 重定向详解

linux shell 重定向详解

[Linux Shell] 重定向分为两种,一种输入重定向,一种是输出重定向;从字面上理解,输入输出重定向就是「改变输入与输出的方向」的意思。

一般情况下,我们都是从键盘读取用户输入的数据,然后再把数据拿到程序(程序、程序等)中使用;这就是标准的输入方向,也就是从键盘到程序。

我们可以把观点提炼一下,其实输入输出方向就是数据的流动方向:

硬件设备和文件描述符

计算机的硬件设备有很多,常见的输入设备有键盘、鼠标、麦克风、手写板等,输出设备有显示器、投影仪、打印机等。不过,在 Linux
Linux 中一切皆文件,包括标准输入设备(键盘)和标准输出设备(显示器)在内的所有计算机硬件都是文件。
文件描述符(File Descriptor)

文件描述符文件名类型硬件
0stdin标准输入文件键盘
1stdout标准输出文件显示器
2stderr标准错误输出文件显示器

Linux 程序在执行任何形式的 I/O 操作时,都是在读取或者写入一个文件描述符。一个文件描述符只是一个和打开的文件相关联的整数,它的背后可能是一个硬盘上的普通文件、FIFO、管道、终端、键盘、显示器,甚至是一个网络连接。

Linux Shell 输出重定向

输出重定向是指命令的结果不再输出到显示器上,而是输出到其它地方,一般是文件中。这样做的最大好处就是把命令的结果保存起来,当我们需要的时候可以随时查询。Bash 支持的输出重定向符号如下表所示。

类 型符 号作 用
标准输出重定向command >file以覆盖的方式,把 command 的正确输出结果输出到 file 文件中。
command >>file以追加的方式,把 command 的正确输出结果输出到 file 文件中。
标准错误输出重定向command 2>file以覆盖的方式,把 command 的错误信息输出到 file 文件中。
command 2>>file以追加的方式,把 command 的错误信息输出到 file 文件中。
正确输出和错误信息同时保存command >file 2>&1以覆盖的方式,把正确输出和错误信息同时保存到同一个文件(file)中。
command >>file 2>&1以追加的方式,把正确输出和错误信息同时保存到同一个文件(file)中。
command >file1 2>file2以覆盖的方式,把正确的输出结果输出到 file1 文件中,把错误信息输出到 file2 文件中。
command >>file1 2>>file2以追加的方式,把正确的输出结果输出到 file1 文件中,把错误信息输出到 file2 文件中。
command >file 2>file不推荐】这两种写法会导致 file 被打开两次,引起资源竞争,所以 stdout 和 stderr 会互相覆盖,我们将在《结合Linux文件描述符谈重定向,彻底理解重定向的本质》一节中深入剖析。
command >>file 2>>file

在输出重定向中,代表的是覆盖,代表的是追加。输出重定向的完整写法其实是或者,其中 fd 表示文件描述符,如果不写,默认为 1,也就是标准输出文件。
command >file``command 1>file
当文件描述符为大于 1 的值时,比如 2,就必须写上。
fd``>``>``file``>
下面的语句是一个反面教材:

echo “c.biancheng.net” 1 >log.txt

注意1``>``c.biancheng.net``c.biancheng.net 1

echo “c.biancheng.net” 1 1>log.txt

输出重定向举例

【实例1】将 echo 命令的输出结果以追加的方式写入到 demo.txt 文件中。

#!/bin/bashfor str in "C语言中文网" "http://c.biancheng.net/" "成立7年了" "日IP数万"do    echo $str >>demo.txt  #将输入结果以追加的方式重定向到文件done

运行以上脚本,使用cat demo.txt

【实例2】将命令的输出结果重定向到文件中。

错误输出重定向举例

命令正确执行是没有错误信息的,我们必须刻意地让命令执行出错,如下所示:

[c.biancheng.net]$ ls java  #先预览一下错误信息
ls: 无法访问java: 没有那个文件或目录
[c.biancheng.net]$ ls java 2>err.log  #重定向
[c.biancheng.net]$ cat err.log  #查看文件
ls: 无法访问java: 没有那个文件或目录
正确输出和错误信息同时保存

【实例1】把正确结果和错误信息都保存到一个文件中,例如:

[c.biancheng.net]$ ls -l >out.log 2>&1
[c.biancheng.net]$ ls java >>out.log 2>&1
[c.biancheng.net]$ cat out.log
总用量 12
drwxr-xr-x. 2 root     root      21 7月   1 2016 abc
-rw-r--r--. 1 mozhiyan mozhiyan 399 3月  11 17:12 demo.sh
-rw-rw-r--. 1 mozhiyan mozhiyan 278 3月  16 17:17 main.c
-rw-rw-r--. 1 mozhiyan mozhiyan   0 3月  22 17:39 out.log
-rwxr-xr-x. 1 mozhiyan mozhiyan 187 3月  22 17:16 test.sh
ls: 无法访问java: 没有那个文件或目录

out.log 的最后一行是错误信息,其它行都是正确的输出结果。
【实例2】上面的实例将正确结果和错误信息都写入同一个文件中,这样会导致视觉上的混乱,不利于以后的检索,所以我建议把正确结果和错误信息分开保存到不同的文件中,也即写成下面的形式:这样一来,正确的输出结果会写入到 out.log,而错误的信息则会写入到 err.log。如果你既不想把命令的输出结果保存到文件,也不想把命令的输出结果显示到屏幕上,干扰命令的执行,那么可以把命令的所有结果重定向到 /dev/null 文件中。如下所示:大家可以把 /dev/null 当成 Linux 系统的垃圾箱,任何放入垃圾箱的数据都会被丢弃,不能恢复。输入重定向就是改变输入的方向,不再使用键盘作为命令输入的来源,而是使用文件作为命令的输入。

fd<file
【示例1】统计文档中有多少行文字。

wc [选项] [文件名]

其中,-c``-w``-l
统计 readme.txt 文件中有多少行文本:

#!/bin/bash

while read str; do
    echo $str
done <readme.txt

运行结果:

这种写法叫做代码块重定向,也就是把一组命令同时重定向到一个文件,我们将在《》一节中详细讲解。

此处我们使用输入重定向符号,这个符号的作用是使用特定的分界符作为命令输入的结束标志,而不使用 Ctrl+D 键。wc 命令会一直等待用输入,直到遇见分界符 END 才结束读取。
之后的分界符可以自由定义,只要再碰到相同的分界符,两个分界符之间的内容将作为命令的输入(不包括分界符本身)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值