Linux输入输出
1.重定向概述
1.什么是重定向
将原本要输出到屏幕的数据信息,重新定向到某个指定的文件中。比如:每天凌晨定时备份数据,希望将备份数据的结果保存到某个文件中。
这样第二天通过查看文件的内容就知道昨天备份的数据是成功还是失败。
2.为何要使用重定向
1.当屏幕输出的信息很重要,而且希望保存重要的信息时;
2.后台执行中的程序,不希望他干扰屏幕正常的输出结果时;
3.系统的例行命令, 例如定时任务的执行结果,希望可以存下来时;
4.一些执行命令,我们已经知道他可能出现错误信息, 想将他直接丢弃时;
5.错误日志与正确日志需要分别输出至不同的文件保存时;
3.学习重定向的预备知识,标准输入与输出
当运行一个程序时通常会自动打开三个标准文件,分别是标准输入、标准输出、错误输出
名称 | 文件描述符 | 作用 |
标准输入(STDIN) | 0 | 默认是键盘,也可以是文件或其他命令的输出。 |
标准输出(STDOUT) | 1 | 默认输出到屏幕。 |
错误输出(STDERR) | 2 | 默认输出到屏幕。 |
文件名称(filename) | 3+ |
-
标准输入 默认是来自键盘的输入 stdin 0
-
标准输出 默认输出到终端窗口 stdout 1
-
标准错误输出 默认输出到终端窗口 stderr 2
2.I/O重定向
改变输出另外的地方,比如重定向输出到终端,改到输出到文件
m[root@192 test]#file /run/gssproxy.sock > c m[root@192 test]#cat c /run/gssproxy.sock: socket
错误输出到文件f中
m[root@192 test]#ls sdjfjei 2> f m[root@192 test]#cat f ls: cannot access sdjfjei: No such file or directory
> 覆盖
-
> 将标准输出重定向到文件中
-
2> 将错误输出重定向到文件中
-
&> 将所有的输出都重定向到文件中
禁止、允许覆盖
m[root@192 test]#>q m[root@192 test]#ls jdjfdk 2>q m[root@192 test]#set -C m[root@192 test]#>q -bash: q: cannot overwrite existing file
-
禁止覆盖 set -C
-
允许覆盖 set +C
>> 追加
m[root@192 test]#ls djfjdkf 2>>a m[root@192 test]#ls djfjdkf 2>>a m[root@192 test]#ls djfjdkf 2>>a m[root@192 test]#cat a ls: cannot access djfjdkf: No such file or directory ls: cannot access djfjdkf: No such file or directory ls: cannot access djfjdkf: No such file or directory
>> 将标准输出追加到文件中
2>> 将错误输出追加到文件中
&>> 将所有输出追加到文件中
[root@localhost ~]#ls f 45yuio > log.log 2> error.log [root@localhost ~]#cat log.log f [root@localhost ~]#cat error.log ls: cannot access 45yuio: No such file or directory
合并所有的输出
-
&> 覆盖重定向
-
&>> 追加重定向
-
command > file 2>&1
-
command >> file 2>&1
# 把错误的也合并到标准输出到r文件 m[root@192 test]#ls f 34jdj > r 2>&1 m[root@192 test]#cat r ls: cannot access 34jdj: No such file or directory f
m[root@192 test]#(ls djfj;ls djfjjjnf) 2>g m[root@192 test]#cat g ls: cannot access djfj: No such file or directory ls: cannot access djfjjjnf: No such file or directory
超级回收站,不断地接受输出
m[root@192 test]#(ls f;ls djfjdk) &> /dev/null
# 测试磁盘速度 m[root@192 test]#dd if=/dev/zero of=j bs=100M count=2 2+0 records in 2+0 records out 209715200 bytes (210 MB) copied, 0.247444 s, 848 MB/s
3.从文件导入stdin
tr 字符替换
-t 截断 -d 删除 -s 压缩,去重 -c 取反 # 从文件中替换 [root@localhost ~]#tr 'a-z' 'A-Z' < /etc/issue \S KERNEL \R ON AN \M [root@localhost ~]#tr 'a-z' 'A-Z' qwertyy QWERTYY 12345678 12345678 ASDFGHJ ASDFGHJ qwertyuio QWERTYUIO ^C [root@localhost ~]#tr ab 12 ab 12 abb 122 asdfghjkl 1sdfghjkl ^C [root@localhost ~]#tr abc 12 ab 12 abc 122 abc 122 ^C [root@localhost ~]#tr ab 123 ab 12 abb 122 avc 1vc qbc q2c abc 12c # 截断 [root@localhost ~]#tr -t abc 12 abc 12c ab 12 # 删除 [root@localhost ~]#tr -d abc qwertyui qwertyui an^H^H n abc artyibrtyuiocrtyuiop rtyirtyuiortyuiop ^C [root@localhost ~]#tr -d abc < /etc/issue \S Kernel \r on n \m [root@localhost ~]#cat /etc/issue \S Kernel \r on an \m [root@localhost ~]#tr -s a abc abc aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabc abc ^C [root@localhost ~]#tr -sc a aasdaaaaaaa aasdaaaaaaa ^[[A^H^H^C [root@localhost ~]#tr -sc a aaaaaaaaabbbbbbbbbbbbbccccccccddddddddddd aaaaaaaaabcd [root@localhost ~]#tr -dc a aaaaaaaaaaaabbbbbbbbbb asdfghjkqwertyuiozxcvbnmxcvbnm,. aaaaaaaaaaaaa ctrl+d 结束 [root@localhost ~]#tr -dc "a\n" asdfghjk a wertyujk;l' asdfghj a [root@localhost test]#tr -d a < issue > issue # 处理完成以后不能写会到源文件,要写到新的文件中 [root@localhost test]#seq 1 10 > b [root@localhost test]#cat b 1 2 3 4 5 6 7 8 9 10 [root@localhost test]#tr -d "\n" < b 12345678910[root@localhost test]#tr -d "\n" < b [root@localhost test]#tr "\n" " " <b 1 2 3 4 5 6 7 8 9 10 [root@localhost test]#tr "\n" " " <b >c [root@localhost test]#cat c 1 2 3 4 5 6 7 8 9 10 [root@localhost test]#tr " " "\n" <c 1 2 3 4 5 6 7 8 9 10
# 第一种方式 [root@localhost test]#cat > f1 qwert wertyui wertyui wertyuiopasdfghjk sdfghjkl sdfyhjkl;sdfghjkl;xcvb # 第二种方式 [root@localhost test]#cat > f2 <<EOF > qwerty > qwertyu > wertyui > qwertyu > EOF EOF 不是必须得,只要两个相同就可以
4.管道
命令1|命令2|命令3
-
把命令1的输出结果当做命令2的输入结果,把命令2的输出结果当成命令3的输入结果
-
默认情况下,管道只能传送标准输出
-
如果需要把错误输出也传递,则需要|&
-
一般用来组合多个命令
-
有一些命令是不接受管道的
[root@localhost test]#ls f1|tr 'a-z' 'A-Z' F1 [root@localhost test]#ls f ls: cannot access f: No such file or directory [root@localhost test]#ls f|tr 'a-z' 'A-Z' ls: cannot access f: No such file or directory [root@localhost test]#ls f|&tr 'a-z' 'A-Z' LS: CANNOT ACCESS F: NO SUCH FILE OR DIRECTORY # 不接受管道 [root@localhost test]#echo file{1..20}|touch touch: missing file operand Try 'touch --help' for more information.
案例1: 将/etc/passwd 中的用户按 UID 大小排序
[root@lqz ~]# sort -t":" -k3 -n /etc/passwd [root@lqz ~]# sort -t":" -k3 -n /etc/passwd -r [root@lqz ~]# sort -t":" -k3 -n /etc/passwd |head
案例2: 统计当前/etc/passwd 中用户使用的 shell 类型
#思路:取出第七列(shell) | 排序(把相同归类)| 去重 [root@lqz ~]# awk -F: '{print $7}' /etc/passwd [root@lqz ~]# awk -F: '{print $7}' /etc/passwd |sort [root@lqz ~]# awk -F: '{print $7}' /etc/passwd |sort |uniq [root@lqz ~]# awk -F: '{print $7}' /etc/passwd |sort |uniq -c
案例4: 统计网站的访问情况 top 20
#思路: 打印所有访问的连接 | 过滤访问网站的连接 | 打印用户的 IP | 排序 | 去重 [root@lqz ~]# yum -y install httpd [root@lqz ~]# systemctl start httpd [root@lqz ~]# systemctl stop firewalld [root@lqz ~]# ss -an |grep :80 |awk -F":" '{print $8}' |sort |uniq -c [root@lqz ~]# ss -an |grep :80 |awk -F":" '{print $8}' |sort |uniq -c |sort -k1 -rn |head -n 20
案例5: 打印当前所有 IP
[root@lqz ~]# ip addr |grep 'inet ' |awk '{print $2}' |awk -F"/" '{print $1}' 127.0.0.1 192.168.69.112
案例6: 打印根分区已用空间的百分比(仅打印数字)
[root@lqz ~]# df |grep '/$' |awk '{print $5}' |awk -F"%" '{print $1}'
PS: 管道命令符能让大家能进一步掌握命令之间的搭配使用方法,进一步提高命令输出值的处理效率。
#选项: -a追加 [root@lqz ~]# ip addr |grep 'inet ' |tee ip.txt |awk -F"/" '{print $1}' |awk '{print $2}' 127.0.0.1 10.0.0.100 [root@lqz ~]# cat ip.txt inet 127.0.0.1/8 scope host lo inet 10.0.0.100/24 brd 192.168.69.255 scope global ens32
重定向与 tee 有他们在使用过程中有什么区别
[root@lqz ~]# date > date.txt #直接将内容写入date.txt文件中 [root@lqz ~]# date |tee date.txt #命令执行会输出至屏幕,但会同时保存一份至date.txt文件中
# which cat|xargs ls- l # ls |xargs rm -fv # ls |xargs cp -rvt /tmp/ -或-> ls | xargs -I {} cp -rv {} /tmp/ # ls |xargs mv -t /tmp/ -或-> ls | xargs -I {} mv {} /tmp