重定向和管道
标准输入和输出:
程序:指令+数据
读入数据: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. > >Detailswhenyou‘reon-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)选项是将新生成的内容追加到文件中。