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

 

posted @ 2022-11-15 10:16  战斗小人  阅读(1553)  评论(0编辑  收藏  举报