0
点赞
收藏
分享

微信扫一扫

IO重定向和管道

1 标准输入和输出

Linux系统中有三个最基本的IO设备

  • 标准输入设备(stdin):对应终端键盘
  • 标准输出设备(stdout):对应终端的显示器
  • 标准错误输出设备(stderr):对应终端的显示器

在Linux系统中,一切皆文件,所以,这三个设备也是以文件的形式存在于系统中;程序从标准输入文件中获取数据,再将运行结果和错误信息输出到标准输出设备和标准错误输出设备;

在虚拟终端中,标准输入输出设备都是当前的终端窗口

[root@rocky86 ~]# ll /dev/std*
lrwxrwxrwx 1 root root 15 Jul 12 10:13 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jul 12 10:13 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jul 12 10:13 /dev/stdout -> /proc/self/fd/1

[root@rocky86 ~]# ll /proc/self/fd/
total 0
lrwx------ 1 root root 64 Jul 12 17:47 0 -> /dev/pts/1
lrwx------ 1 root root 64 Jul 12 17:47 1 -> /dev/pts/1
lrwx------ 1 root root 64 Jul 12 17:47 2 -> /dev/pts/1

[root@rocky86 ~]# tty
/dev/pts/1

2 IO重定向 redirect

将默认的输入,输出或错误对应的设备改变,指向新的目标

2.1 标准输出和错误重新定向

STDOUT和STDERR默认是使用当前终端,但也可以重定向到指定终端或指定文件

格式:

COMMAND OPERATOR FILE|DEVICE

#覆盖操作符,如果文件存在,会被覆盖
>       #把STDOUT重定向到文件
1>      #同上
2>      #把STDERR重定向到文件
&>      #把标准输出和错误都重定向
>&      #和上面功能一样,建议使用上面方式

#追加操作符,在原有文件的基础上追加内容
>>      #追加标准输出重定向至文件
1>>     #同上
2>>     #追加标准错误重定向至文件

示例:标准输出和错误输出各自定向至不同位置

[root@rocky86 ~]# ls fstab null
ls: cannot access 'null': No such file or directory fstab

[root@rocky86 ~]# ls fstab null > out.log 2> err.log

示例:合并标准输出和错误输出为同一个数据流进行重定向

#标准输出重定向至 out.log,标准错误输出重定向至标准输出
[root@rocky86 ~]# ls fstab null > out.log 2>&1
[root@rocky86 ~]# ls fstab null &> out.log

#标准错误输出重定向到 out.log,标准输出重定向至标准错误输出
[root@rocky86 ~]# ls fstab null 2> out.log 1>&2

或者
[root@rocky86 ~]# ls fstab null &> out.log

[root@rocky86 ~]# ls fstab null >& out.log

错误写法

#标准错误输出重定向至标准输出之前,要先定义好标准输出的文件
[root@rocky86 ~]# ls fstab null 2>&1 > out.log

#标准输出重定向至标准错误输出之前,要先定义好标准错误输出的文件
[root@rocky86 ~]# ls fstab null 1>&2 2>out.log

2.2 标准输入重定向

  • 标准输入重定向是从文件中读取数据,代替当前终端的输入设备进行数据的输入
  • 此处要严格区分命令是否支持标准输入,标准输入和参数是两个概念
  • 怎么判断命令能使用标准输入重定向?不跟任何选项参数,直接回车,看是否等待标准输入,如果是,则该命令可以使用标准输入重定向

格式:

COMMAND 0< FILE
COMMAND < FILE

示例:

#新建a.txt文件
[root@rocky86 ~]# cat a.txt
1+2+3+4+5+6+7+8+9+10

#等价于cat a.txt
[root@rocky86 ~]# cat < a.txt
1+2+3+4+5+6+7+8+9+10

#输入重定向,再将输入内容输出重定向
[root@rocky86 ~]# cat < a.txt > b.txt
[root@rocky86 ~]# cat b.txt
1+2+3+4+5+6+7+8+9+10

2.3 标准输入多行重定向

  • 使用 "<<终止词" 命令从键盘把多行重导向给STDIN,直到终止词位置之前的所有文本都发送给STDIN
  • 有时被称为就地文本(here documents),其中终止词可以是任何一个或多个符号,比如:!,@,$,EOF(End Of File)等,其中EOF比较常用

示例:

[root@rocky86 ~]# cat <<EOF
> 123       #输入内容
> eof       #输入内容
> EOF       #终止词
123         #输入结果显示
eof         #输入结果显示

2.4高级重定向写法

2.4.1 cmd <<< "string"

含义是 here-string ,表示传给给cmd的stdin的内容从这里开始是一个字符串。

示例:执行命令作重定向输入

[root@rocky86 ~]# bc <<< `echo 1+2+3`
6

[root@rocky86 ~]# bc <<< `seq -s + 3`
6

[root@rocky86 ~]# tr 'a-z' 'A-Z' <<< `hostname`
ROCKY86

2.4.2 cmd1 < <(cmd2)

名称为 Process substitution ,是由两个部分组成

  • <(cmd2) 表示把cmd2的输出写入一个临时文件, 注意:< 符号 与( 符号之间没有空格
  • cmd1 < 这是一个标准的stdin重定向

把两个合起来,就是把cmd2的输出stdout传递给cmd1作为输入stdin, 中间通过临时文件做传递

示例:

[root@rocky86 ~]# bc < <(echo 1+2+3)
6

[root@rocky86 ~]# bc < <(seq -s + 3)
6

[root@rocky86 ~]# tr 'a-z' 'A-Z' < <(hostname)
ROCKY86

示例:查看中间文件

[root@rocky86 ~]# ll <(hostname)
lr-x------ 1 root root 64 Jul 12 23:23 /dev/fd/63 -> 'pipe:[118809]'

3 管道

管道(pipe):名顾思义,水管,从一端进去,再从另一端出来。

在shell 中,可以将两个或多个命令(程序|进程)连接起来,将前一个命令的输出作为后一个命令的输入, 就像拿水管将两个命令连起来;

使用管道,要求前一个命令必须支持标准输出,后一个命令必须支持标准输入;

IO重定向和管道_标准输出

格式:

COMMAND1|COMMAND2|COMMAND3|...

功能说明:

  • 将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
  • 所有命令会在当前shell进程的子shell进程中执行
  • 组合多种工具的功能

注意:STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现,格式如下

COMMAND1 2>&1 | COMMAND2
COMMAND1 |& COMMAND2

示例:

[root@rocky86 ~]# echo 1+2+3|bc
6

[root@rocky86 ~]# ls --help | grep size

#多重管道
[root@rocky86 ~]# echo $PATH | tr ':' '\n' | sort
/root/bin
/usr/bin
/usr/local/bin
/usr/local/sbin
/usr/sbin

#多重管道
[root@rocky86 ~]# ifconfig | head -n 2 | tail -n 1 | tr -s ' ' | cut -d" " -f3
10.0.0.162








举报

相关推荐

0 条评论