重定向和管道
输入和输出
程序是由指令加数据组成的,一般情况下都会有输入(Input)和输出(Output),当你由程序打开一个文件的时候就会产生一个文件描述符(file descriptor)。在Linux中有三种IO设备,分别是:
stdin:标准输入,默认情况下接受来自键盘的输入
stdpout:标准输出,默认情况下输出到终端的窗口
stderr:错误输出,默认情况输出终端的窗口
重定向
在默认情况下,stdout和stderr都是被输出到终端的,但是有时候,我们需要将其输出到指定的终端或者指定的文件记录下来,所有就有了重定向的概念
输出重定向
重定向符号 | 若文件不存在 | 若文件存在 |
---|---|---|
> | 创建,并将正确的输出写入到文件中 | 将正确的内容覆盖至目标文件 |
>> | 创建,并将正确输出写入到文件中 | 将正确的内容追加至目标文件 |
2> | 创建,并将错误输出写到文件中 | 将错误的内容覆盖至目标文件 |
2>> | 创建,并将错误输出写到文件中 | 将错误的内容追加至目标文件 |
&> | 创建,并将所有输出写到文件中 | 将所有的内容覆盖至目标文件 |
&>> | 创建,并将所有输出写到文件中 | 将所有的内容追加至目标文件 |
在使用>>的时候,可能不小心就敲成>,就会造成有些重要数据的被覆盖从而丢失,这时候就可以通过set -C来禁止内容覆盖,因为系统默认是set +C允许覆盖,还可以使用>|来强制覆盖
[root@centos6 app]# echo nihao > nihao.txt
[root@centos6 app]# cat nihao.txt
nihao
[root@centos6 app]# set -C
[root@centos6 app]# echo hello > nihao.txt
-bash: nihao.txt: cannot overwrite existing file
[root@centos6 app]# echo hello >| nihao.txt
[root@centos6 app]# cat nihao.txt
hello
标准输出和错误输出可以重定向至不同的位置
[fanjie@centos6 ~]$ find /etc/ -name "*.conf" > /app/a.out 2> /app/b.err
可以使用()合并多个命令执行的结果到一个文件中
[root@centos6 app]# (cat /etc/passwd;cat /etc/shadow) > /app/etc.txt
正确输出和错误输出之间的相互切换
使用2>&1将错误结果转换正确结果
[fanjie@centos6 app]$ cat find.out |wc -l
406
[fanjie@centos6 app]$ find /etc/ -name "*.conf" > find.out 2>&1
[fanjie@centos6 app]$ cat find.out |wc -l
420
使用1>&2将正确结果转换错误结果
[fanjie@centos6 app]$ cat find.out |wc -l
14
[fanjie@centos6 app]$ find /etc/ -name "*.conf" 2> find.out 1>&
2
[fanjie@centos6 app]$ cat find.out |wc -l
420
以上两种方法其实和下面的方式的输出结果是一样的,这里使用的是&>
[fanjie@centos6 app]$ find /etc/ -name "*.conf" &> find.out
[fanjie@centos6 app]$ cat find.out |wc -l
420
输入重定向
从文件中导入到stdin
使用<来重定向标准输入,下面的例子就是将/etc/default/useradd的内容全部转换成大写
[root@centos6 app]# tr 'a-z' 'A-Z' < /etc/default/useradd
# USERADD DEFAULTS FILE
GROUP=100
HOME=/HOME
INACTIVE=-1
EXPIRE=
SHELL=/BIN/BASH
SKEL=/ETC/SKEL
CREATE_MAIL_SPOOL=YES
比如现在我们想把/etc/fstab里面的abc中的任意字符删掉
[root@centos6 app]# tr -d "abc" < /etc/fstab
可以使用cat新建一个文件,然后键入内容,输入完成用Ctrl + d来完成
[root@centos6 app]# cat > test.txt
nihao
hello
[root@centos6 app]# cat test.txt
nihao
hello
也可以将文件的内容输入到另一个文件,相当于是复制了一个文件
[root@centos6 app]# echo nihao > 1.txt
[root@centos6 app]# cat 1.txt
nihao
[root@centos6 app]# cat >2.txt < 1.txt
[root@centos6 app]# cat 2.txt
nihao
多行发送给stdin
[root@centos6 app]# cat > file << EOF
> nihao
> hello
> EOF
[root@centos6 app]# cat file
nihao
hello
垃圾桶
当有的输出结果我们不需要时,就可以将其输出到/dev/null下
tr
转换和删除字符,常用选项:
- -t:将第一个字符集对应的字符转换为第二个字符集对应的字符,默认
- -d:删除所有第一字符集的字符
- -s:把连续重复的字符以单独一个字符表示
- -c:取字符集的补集
[root@centos6 app]# echo abcabc |tr ab x
xxcxxc
[root@centos6 app]# echo 1234567890 |tr 123 abcdef
abc4567890
[root@centos6 app]# echo aaabcbbbde |tr -s ab x
xcxde
[root@centos6 app]# echo aaabcbbbde |tr -s ab
abcbde
[root@centos6 app]# cat -A tr.txt
abcabc$
[root@centos6 app]# cat tr.txt |tr -c ab x
abxabxx[root@centos6 app]#
管道
管道是用来连接命令的,将前面命令的正确输出给后面命令的标准输入。stderr默认不能通过管道转发,可以利用2>&1或者是|&实现
[root@centos7 app]$ find /etc/ -name "*.conf" 2>&1 |wc -l
344
[root@centos7 app]$ find /etc/ -name "*.conf" |& wc -l
344
less
可以用man下的快捷键操作,相当于把输出结果放在man下查看
tee
重定向到多个目标,把/etc/default/useradd的内容转换成大写保存一份,然后在终端输出结果
[root@centos6 app]# cat /etc/default/useradd |tee useradd.txt |tr a-z A-Z
# USERADD DEFAULTS FILE
GROUP=100
HOME=/HOME
INACTIVE=-1
EXPIRE=
SHELL=/BIN/BASH
SKEL=/ETC/SKEL
CREATE_MAIL_SPOOL=YES
[root@centos6 app]# cat useradd.txt
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
练习
-
将/etc/issue文件中的内容转换为大写后保存至/app/issue.out文件中
[root@centos6 app]# cat /etc/issue |tr a-z A-Z > /app/issue.out
-
将当前系统登录用户的信息转换为大写后保存至/app/who.out文件中
[root@centos6 app]# who am i |tr a-z A-Z > /app/who.out
-
一个linux用户给root发邮件,要求邮件标题为”help”,邮件正文如下:
Hello, I am 用户名,The system version is here,please help me to check it thanks!
操作系统版本信息[fanjie@centos7 ~]$ mail -s "help" root <<EOF Hello, I am $(whoami),The system version is here,please help me to check it thanks! `cat /etc/redhat-release` EOF
-
将/root/下文件列表,显示成一行,并文件名之间用空格隔开
[root@centos6 app]# ls /root/ |tr [:space:] ' ' anaconda-ks.cfg Desktop Documents Downloads install.log install.log.syslog Music Pictures Public Templates tr Videos [root@centos6 app]# ls /root/ |tr '\n' ' ' anaconda-ks.cfg Desktop Documents Downloads install.log install.log.syslog Music Pictures Public Templates tr Videos
-
计算1+2+3+..+99+100的总和
[root@centos6 app]# echo {1..100} |tr [:blank:] + |bc 5050 [root@centos6 app]# echo {1..100} |tr ' ' + |bc 5050
-
删除Windows文本文件中的‘^M’字符
[root@centos6 app]# cat windows.txt |tr -d '\r' |cat -A a$ b$ c$ d$ e$
-
处理字符串“xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4”,只保留其中的数字和空格
[root@centos6 app]# echo xt.,l 1 jr#-Amn 2 c*/fe 3 uz 4 |tr -d [:alpha:][:punct:] 1 2 3 4 [root@centos6 app]# echo xt.,l 1 jr#-Amn 2 c*/fe 3 uz 4 |tr -cd [:digit:][:blank:] 1 2 3 4
-
将PATH变量每个目录显示在独立的一行
[root@centos6 app]# echo $PATH |tr : '\n'
-
将指定文件中0-9分别替代成a-j
[root@centos6 app]# echo 9876543210 |tr 0-9 a-j jihgfedcba
-
将文件中每个单词(由字母组成)显示在独立的一行,并无空行
[root@centos6 app]# echo nihao hello fanjie |tr [:blank:] '\n'