Linux基础11 重定向(输入重定向,输出重定向); 管道技术, tee, xargs
1.重定向
将原本要输出到屏幕上的内容,重新指向一个文件或者设备中,屏幕上不会输出原本的内容。
为什么要使用重定向:
1.当屏幕输出的信息很重要,而且希望保存重要的信息时。
2.后台执行中的程序,不希望他干扰屏幕正常的输出结果时。
3.系统的例行命令, 例如定时任务的执行结果,希望他可以存下来时。
4.一些执行命令,我们已经知道他可能出现错误信息, 想将他直接丢弃时。
5.执行一个命令,可能报错和正确的输出并存,类似错误日志与标准正确日志需要分别输出至不同的文件。
运行程序,或者输入一个命令:默认打开4个文件描述符
标准输入 输出分类:
0:标准输入
1:标准输出
2:错误输出
3+:文件名
/dev/stderr(错误输出) -> /proc/self/fd/2 2 -> /dev/pts/0 (终端窗口,这里为0,可以用tty查看) /dev/stdin(标准输入) -> /proc/self/fd/0 0 -> /dev/pts/0 /dev/stdout(标准输出) -> /proc/self/fd/1 1 -> /dev/pts/0
2.输出重定向分类
重定向的特性:覆盖文件
1>(>):标准输出重定向,将命令执行的正确结果输出到指定的文件或者设备中
2>:错误输出重定向
追加重定向:不会覆盖文件
1>>(>>):标准输出追加重定向,将命令执行的正确结果追加输出到文件末尾
2>>:错输出追加重定向,将命令执行的错误结果追加输出到文件末尾
<<:标准输入重定向:将键盘敲的内容,输入到命令或者文件中
3.输出重定向的使用:
#将正确内容重定向到文件中,错误会输出到屏幕(会覆盖源文件) ifconfig eth0 > abc #将正确的内容追加到文件中,错误会输出到屏幕(不会覆盖源文件) echo "This is network conf" >> abc #将错误的内容输出到文件中,正确的会输出到屏幕(会覆盖源文件) find /etc -name "*.conf" 2>b find /etc -name "*.conf" 1>a 2>b #合并输出,错误的正确的内容都会输出到一个文件(会覆盖源文件) find /etc -name "*.conf" >c 2>&1 # &1表示输出到1的地址中 find /etc -name "*.conf" >c 2>c find /etc -name "*.conf" &>c # &表示混合,把1和2都写入 &>> 标准输出和错误重定向追加 #将错误输出重定向到 ‘黑洞’,正确内容输出到屏幕/dev/pts/x ls /root/ /err 2>/dev/null #将错误输出重定向到 ‘黑洞’,正确内容输出到1.txt文件中 ls /root/ /err >1.txt 2>/dev/null
4.输入的重定向使用
COMMAND 0< FILE #输入设备0,这里永远是0,所以可以不要
COMMAND < FILE
< :0< << :0<< 案例1: cat >> zls.txt <<eof zls qiudao eof 案例2: [root@zls ~]# mail zls < /etc/passwd 案例3: [root@oldboyedu ~]# grep 'root' rppr qwe rootasdasdadzxczxc rootasdasdadzxczxc ^C 案例4: [root@oldboyedu ~]# dd if=/dev/zero of=/file1.txt bs=1M count=20 20+0 records in 20+0 records out 20971520 bytes (21 MB) copied, 0.0260574 s, 805 MB/s [root@oldboyedu ~]# dd </dev/zero >/file2.txt bs=1M count=20 # /dev/zero不断产生0, 通过dd命令, 写入file2.txt中 20+0 records in 20+0 records out 20971520 bytes (21 MB) copied, 0.011896 s, 1.8 GB/s 案例5: 恢复mysql数据 [root@zls ~]# mysql -uroot -p123 < bbs.sql 案例6:利用重定向建立多行文件 [root@oldboyedu ~]# cat >file1 案例7: #!/bin/sh menu(){ cat <<EOF +------------+ | 1 | apple | +---+--------+ | 2 | pear | +---+--------+ | 3 | banana | +---+--------+ | 4 | cherry | +---+--------+ EOF read -p "please input a num: " fruit } usage(){ echo "USAGE:请输入水果编号" exit 1 } color(){ case "$fruit" in 1) echo -e "\E[1;31mapple \E[0m" ;; 2) echo -e "\E[1;20mpear \E[0m" ;; 3) echo -e "\E[1;33mbanana \E[0m" ;; 4) echo -e "\E[1;35mcherry \E[0m" ;; *) usage esac } menu color 案例8:多条命令重定向 [root@oldboyedu ~]# (ls;date) > a.txt # 不加括号只会把后面的命令重定向, ;表示2命令都要执行 案例9:后台进程重定向 (while :; do date; sleep 2; done) &>/dev/null & # &比较特殊,后台运行的&一定要放在最后,否则重定向不起效果
5.管道技术 |
连接多个命令,将管道符左侧的标准输出,交给管道符右侧的命令标准输入
案例1: 将/etc/passwd 中的UID取出并按大小排序 [root@oldboyedu ~]# awk -F : '{print $3}' /etc/passwd|sort -n 案例2: 统计当前/etc/passwd 中用户使用的 shell 类型 [root@oldboyedu ~]# awk -F : '{print $NF}' /etc/passwd|sort |uniq|wc -l # sort排序,uniq去重,wc统计 5 案例3:统计最占cpu的5个进程 案例4:统计网站访问量top20 [root@driver-zeng nginx]# awk '{print $1}' driverzeng.com_access.log|sort |uniq -c|sort -nr|head -20 案例5:取出cpu已使用的百分比,只显示数字 [root@oldboyedu ~]# df -h |awk -F '[ %]+' 'NR==2 {print $5}' 4
注意:STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现,格式如下
COMMAND1 2>&1 | COMMAND2
COMMAND1 |& COMMAND2
tee:
显示程序的输出并将其复制到一个文件中。
date |tee b.txt # 输出date的同时, 记录到b.txt中
-a 追加
md1 | tee [-a ] filename | cmd2
#接受标准输入,在标准输出上打印,并写文件 [root@ubuntu2204 ~]# tee tee.log #管道重定向 [root@ubuntu2204 ~]# echo hello | tee tee.log hello #tee.log 里面是hello,终端输出是HELLO [root@ubuntu2204 ~]# echo hello | tee tee.log | tr 'a-z' 'A-Z' HELLO #tee.log 和终端输出都是大写 [root@ubuntu2204 ~]# echo hello | tr 'a-z' 'A-Z' | tee tee.log HELLO #追加 [root@ubuntu2204 ~]# echo hello | tr 'a-z' 'A-Z' | tee -a tee.log HELLO
xargs:
有些命令没有标准输入,通过|xargs 将前面命令的标准输出,交给后面命令来处理
find /etc/ -name '*.conf'|xargs ls -l # 把find获取到的通过xargs给后面的命令ls作为参数使用
-I 指定占位符
说明:用于提供输入信息,可以随便准备,比如直接显示某个目录下的所有文件也可以
[root@localhost ~]# find . -name "*.ini" ./.pycharm_helpers/pydev/pytest.ini ./.pycharm_helpers/pydev/tox.ini ./abc.ini # 使用方法:通过-I进行显示 # xargs缺省使用echo进行显示,这里指定-I 进行显示 [root@localhost ~]# find . -name "*.ini"|xargs -I {} echo {} ./.pycharm_helpers/pydev/pytest.ini ./.pycharm_helpers/pydev/tox.ini ./abc.ini # 和缺省xargs动作的比较 # 由于此处演示使用的是echo命令,和缺省的xargs动作几乎一致 [root@localhost ~]# find . -name '*.tar.gz' |xargs echo # 通过如下的执行,可以更加清楚地理解占位符的意义,首先,指定-I 之后我们不传给echo命令,可以看到显示为三个空行 [root@localhost ~]# find . -name "*.ini"|xargs -I {} echo # 由此扩展可以将占位符指定为多于一个参数的指定位置,比如mv 和cp等常用命令
格式:
xargs [OPTION]... COMMAND [INITIAL-ARGS]... #常用选项 -0|--null #用 assic 中的0或 null 作分隔符 -a|--arg-file=FILE #从文件中读入作为输入 -d|--delimiter=CHARACTER #指定分隔符 -E END #指定结束符,执行到此处时停止,不管后面的数据 -L|--max-lines=N #从标准输入一次读取N行送给 command 命令 -l #同上 -n|--max-args=MAX-ARGS #一次执行用几个参数 -p|--interactive #每次执行前确认 -r|--no-run-if-empty #当xargs的输入为空的时候则停止xargs,不用再去执行了 -s|--max-chars=MAX-CHARS #命令行最大字符数 -t|--verbose #显示过程,先打印要执行的命令 -x|--exit #退出,主要配合-s使用
#指定分割符 [root@ubuntu2204 ~]# echo -e "1-2-3\c" | xargs -d '-' 1 2 3 #指定每次使用2个参数 [root@ubuntu2204 ~]# echo {1..5} | xargs -n 2 1 2 3 4 5 #批量创建用户并显示命令 [root@ubuntu2204 ~]# echo user{1..5} |xargs -t -n1 useradd useradd user1 useradd user2 useradd user3 useradd user4 useradd user5 #批量删除用户 [root@ubuntu2204 ~]# echo user{1..5} |xargs -n1 userdel -r #参数太长,执行失败 [root@ubuntu2204 test]# touch f-{1..130752}.txt -bash: /usr/bin/touch: Argument list too long #一次创建1w个 [root@ubuntu2204 test]# echo f-{1..130752}.txt | xargs -n 10000 touch