第五章 linux重定向和管道

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第五章 linux重定向和管道相关的知识,希望对你有一定的参考价值。

重定向和管道

标准输入和输出:

程序:指令+数据

读入数据:Input

输出数据:Output

打开的文件都有一个fd: file descriptor (文件描述符)

Linux给程序提供三种I/O设备

  • 标准输入(STDIN)-0默认接受来自键盘的输入
  • 标准输出(STDOUT)-1默认输出到终端窗口
  • 标准错误(STDERR)-2默认输出到终端窗口

I/O重定向:改变默认位置

[[email protected] /app]#ls >/dev/pts/7

本终端窗口不进行输出,将结果输出到别的终端窗口。

把输出和错误重新定向到文件:

STDOUT和STDERR可以被重定向到文件

命令  操作符号  文件名

支持的操作符号包括:

> 把STDOUT重定向到文件

2>把STDERR重定向到文件

&>把所有输出重定向到文件

> 文件内容会被覆盖

set –C 禁止将内容覆盖已有文件,但可追加

>| file 强制覆盖

set +C 允许覆盖

>> 原有内容基础上,追加内容,原文件存在不刷新时间戳

2>覆盖重定向错误输出数据流

2>>追加重定向错误输出数据流

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

COMMAND > /path/to/file.out2> /path/to/error.out

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

&>覆盖重定向

&>> 追加重定向

COMMAND > /path/to/file.out2>&1 (顺序很重要)

COMMAND >> /path/to/file.out2>&1

():合并多个程序的STDOUT

(cal2007;cal2008)> all.txt

[[email protected] /app]#(hostname;whoami;ls)>a.txt
[[email protected]
/app]#cat a.txt
localhost.localdomain
root
a aaaa f
lost
+found

加上( )把三个命令的结果全部添加到文件a.txt中。如果不加( )由于优先级问题就会先执行>即a.txt中的内容为ls执行的结果。

[[email protected] /app]#(error;hostname)>aaa.log   2>&1

把错误的重定向到标准输出,而标准输出是放到aaa.log文件中的。

[[email protected] /app]#(error;hostname)  2>&1  >a

-bash: error: command not found

2>&1放前面和后面是完全不一样的结果,前一条命令直接变成对的输出到屏幕,后一条命令是对的直接输出到文件。

[[email protected] /app]#((error;hostname) 2>&1) >a

[[email protected] /app]#cat a

-bash: error: command not found

localhost.localdomain

这样加上( )经过转换就可以了。

[[email protected] /app]#(error;hostname)&>aaa.log   

等价于上一条执行的命令。

[[email protected] /app]#ls >/dev/null

/dev/null是黑洞设备,不需要输出到窗口的信息可以重定向到这里。

[[email protected] /app]#(echo error 1>&2) > /dev/null

error

把对的转化为错的,显示的结果不能标准输出到/dev/null中

tr命令:

tr转换和删除字符

tr[OPTION]... SET1 [SET2]

选项:

-c–C --complement:取字符集的补集

-d--delete:删除所有属于第一字符集的字符

-s--squeeze-repeats:把连续重复的字符以单独一个字符表示

-t--truncate-set1:将第一个字符集对应字符转化为第二字符集

对应的字符

[:alnum:]:字母和数字   [:alpha:]:字母[:cntrl:]:控制(非打印)字符[:digit:]:数字         [:graph:]:图形字符     [:lower:]:小写字母[:print:]:可打印字符   [:punct:]:标点符号     [:space:]:空白字符   [:upper:]:大写字母     [:xdigit:]:十六进制字符

从文件中导入STDIN:

使用<来重定向标准输入

某些命令能够接受从文件中导入的STDIN

tr‘a-z’‘A-Z’</etc/issue

该命令会把/etc/issue中的小写字符都转换成大写字符

tr –d abc < /etc/fstab 删除fstab文件中的所有abc中任意字符

cat > file

sunan

sunanblog.com

按ctrl+d离开,可以使用文件来代替键盘的输入

cat > filea <fileb

[[email protected] /app]#tr 123 ab

123456123

abb456abb

3没有代替的直接用b代替。

[[email protected] /app]#tr  -t 123 ab

12345123456

ab345ab3456

-t选项是截断,相当于3不要了。

[[email protected] /app]#tr -d a-z<fstab

# A ,  ,    //

# S   (5), (8), (8) / (8)  

#

UUID=044064-970-41-9-74526493 /                       4            1 1

UUID=859743-0-49-26-803582 /                    4            1 2

UUID=0759--4156-25-23245 /                   4            1 2

UUID=435474-0-47-459-152686446                                 0 0
......

将文件中的小写字母全部删掉。

[[email protected] /app]#tr -d a-z<fstab >fstab2

[[email protected] /app]#cat fstab2

#
......

UUID=044064-970-41-9-74526493 /                       4            1 1

UUID=859743-0-49-26-803582 /                    4            1 2

UUID=0759--4156-25-23245 /                   4            1 2

UUID=435474-0-47-459-152686446                                 0 0
......

转化过后重定向到新的文件中。

[[email protected] /app]#tr -d a-z<fstab >fstab

上面的命令执行会把fstab文件中的内容清空,在单一命令中,一次只能处理一次,打开的同时再重定向是不行的,只能换一个新的文件名。

[[email protected] /app]#tr -s a

asdfaaaaasdfsdfsaaaa

asdfasdfsdfsa

-s是将重复的a进行压缩。

[[email protected] /app]#tr -dc a      

asdfvdssd

sdfas

sdfasdf

这条命令按回车是不会执行的,因为-c是取a的补集,-d是删除,即除了a意思是包括\n回车也会当成输入来执行,只能按Ctrl+d进行处理。

[[email protected] /app]#tr -dc a\n 

asdfsdfaaa

aaaa

这样加上回车换行\n就可以了。

[[email protected] /app]#cat win.txt

a

b

c[[email protected] /app]#

查看windows上传的win.txt文件

[[email protected] /app]#hexdump  -C win.txt

00000000  61 0d 0a 62 0d 0a 63                              |a..b..c|

00000007

查看windows上传的文件的16进制编码

[[email protected] /app]#cat linux.txt

a

b

c

[[email protected] /app]#

查看linux上的文件linux.txt,内容是一样的。l

[[email protected] /app]#hexdump  -C linux.txt

00000000  61 0a 62 0a 63 0a                                 |a.b.c.|

00000006

查看Linux上的文件和Windows上传文件内容一样。但inux上以前为了节省空间,把回车和换行用一个换行表示,windows上回车是回车换行是换行。

[[email protected] /app]#tr -d \r <win.txt  >newwin.txt

[[email protected] /app]#hexdump  -C newwin.txt

00000000  61 0a 62 0a 63                                    |a.b.c|

00000005

这条命令就把windows文件转换为linux文件了,说明windows中的文件和linux中的文件是不同的。

[[email protected] /app]#hexdump  -c linux.txt

0000000   a  \n   b  \n   c  \n                                       

0000006

[[email protected] /app]#hexdump  -c win.txt

0000000   a  \r  \n   b  \r  \n   c                                   

0000007

加小c选项可以直接看到回车和换行。

[[email protected] /app]#dos2unix  win.txt

dos2unix: converting file win.txt to UNIX format ...

[[email protected] /app]#hexdump  -c win.txt                  

0000000   a  \n   b  \n   c                                           

0000005

使用dos2unix可以直接windows文件格式直接转换linux文件格式,当然,unix2dos是转换回去。

[[email protected] /app]#cat aa        

aaa

bbb

ccc

[[email protected] /app]#tr \n \t <aa

aaa     bbb     ccc     [[email protected] /app]#

[[email protected] /app]#

[[email protected] /app]#tr \n \v <aa

aaa

   bbb

      ccc

         [[email protected] /app]#

将文件中的换行替换成水平tab键(水平制表符)和垂直tab键(垂直制表符)

把多行发送给STDIN:

使用“<<终止词”命令从键盘把多行重导向给STDIN

直到终止词位置的所有文本都发送给STDIN

有时被称为就地文本(heretext)

mail -s "PleaseCall" root<<END

>HiSun,

> 

>Pleasegivemeacallwhenyougetin.Wemayneed

>todosomemaintenanceonserver1.

> 

>Detailswhenyoureon-site

>sun

>END

向root发送邮件

[[email protected] ~]#>/var/spool/mail/root

清空邮件。

[[email protected] /]#mail -s "hello" root <<END

asddf

END

[[email protected] /]#send-mail: warning: valid_hostname: numeric hostname: 9

send-mail: fatal: file /etc/postfix/main.cf: parameter mydomain: bad parameter value: 9

mai发送各种失败,不知道为什么,只能网上搜索答案。

[[email protected] ~]#hostnamectl set-hostname localhost 

需要上面这条命令,然后重启机器就好了,网上答案说单机模式主机名需要改为localhost,至于为什么再做研究。

管道:

管道(使用符号“|”表示)用来连接命令

命令1 | 命令2 | 命令3 | …

将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN

STDERR默认不能通过管道转发,可利用2>&1 或|& 实现

最后一个命令会在当前shell进程的子shell进程中执行用来

组合多种工具的功能

ls | tr ‘a-z‘ ‘A-Z‘

less :一页一页地查看输入

ls-l/etc|less

mail:通过电子邮件发送输入

echo"testemail"|mail-s "test"[email protected]

lpr:把输入发送给打印机

echo"testprint"|lpr-Pprinter_name

管道中的 – 符号

示例:

将/home 里面的文件打包,但打包的数据不是记录到文件,而是传送到stdout,经过管道后,将tar -cvf-/home 传送给后面的tar -xvf-, 后面的这个-则是取前一个命令的stdout,因此,就不需要使用临时file了

tar -cvf-/home | tar -xvf-

重定向到多个目标:

命令1 | tee[-a ] 文件名| 命令2

把命令1的STDOUT保存在文件中,做为命令2的输入 -a 追加

使用:

保存不同阶段的输出

复杂管道的故障排除

同时查看和记录输出

[[email protected] /app]#ls |tee ls.out

lost+found

newwin.txt

win.txt

win..txt

[[email protected] /app]#cat ls.out

lost+found

newwin.txt

win.txt

win..txt

既想在屏幕输出又想保存到文件可以用tee命令

[[email protected] /app]#pwd  |tee -a  ls.out

/app

[[email protected] /app]#cat ls.out         

lost+found

newwin.txt

win.txt

win..txt

/app

-a(append)选项是将新生成的内容追加到文件中。

以上是关于第五章 linux重定向和管道的主要内容,如果未能解决你的问题,请参考以下文章

Linux入门-7 Linux管道重定向以及文本处理

谈谈Linux下的数据流重定向和管道命令

Linux管道及重定向

Linux重定向与管道简述

Linux中重定向管道和grep命令总结

Linux中重定向管道和grep命令总结