第六章:管道符及重定向
I/O重定向 | 管道符号
标准输入、 标准输出、 标准错误
1 ----------------- 2 --------------- 3 --------------3+
输出重定向【追加覆盖】
正确输出:1> 1>> //覆盖> 追加>>
错误输出:2> 2>>
=======================================================================================
本章全部由实战演示:
一.输出重定向
1.1. 案例1:输出重定向(覆盖)
正确输出 : 1> 1>> 【 > >> 】
[root@lxw2 ~]# date 1> date.txt //date时间 标准输出,把时间覆盖至date.txt1.2.案例2:输出重定向(追加)
[root@lxw2 ~]# date >> date.txt //追加时间给date.txt
[root@lxw2 ~]# cat date.txt
2020年 09月 17日 星期四 02:01:03 CST
2020年 09月 17日 星期四 02:02:48 CST1.3. 案例3:错误输出重定向
[root@lxw2 ~]# ls /home/ /aaaaaaaaa >>list.txt //错误输出重定向,但是追加项目会执行
ls: 无法访问/aaaaaaaaa: 没有那个文件或目录
[root@lxw2 ~]# ls
a.txt date.txt list.txt1.4.正确和错误都输入到相同位置
[root@lxw2 ~]# ls /home/ /aaaaa $>list.txt //混合输出
[root@lxw2 ~]# ls /home/ aaaaa $>list.txt //混合输出1.5. 正确和错误都输入到相同位置
[root@lxw2 ~]# ls /home/ /a.txt >b.txt 2>&1 //[root@lxw2 ~]# ls /home/ /a.txt >b.txt 2>&1date > date.txt 标准输出重定向 【覆盖】
date >> date.txt 彼岸准输出重定向 【追加】
ls /fafaga 2> err.txt 标准错误重定向 【覆盖】
ls /fafaga 2>> err.txt 标准错误重定向 【追加】
ls /home /afsfa &>a.txt 混合输出
ls /home /afsfa >a.txt 2>&2 输入到同一个文件 【结果和上个一样,原理不同】普通文件和设备文件:
[root@lxw2 ~]# ll /dev/null /dev/sda1 /etc/hosts
crw-rw-rw-. 1 root root 1, 3 9月 16 16:39 /dev/null
brw-rw----. 1 root disk 8, 1 9月 16 16:39 /dev/sda1
-rw-r--r--. 1 root root 158 6月 7 2013 /etc/hosts特殊设备
[root@lxw2 ~]#ll /dev/null //可以吞噬一切数据
[root@lxw2 ~]#ll /dev/zero //可以产生无线的数据
crw-rw-rw-. 1 root root 1, 3 9月 16 16:39 /dev/null
crw-rw-rw-. 1 root root 1, 5 9月 16 16:39 /dev/zero
脚本中使用重定向
案例1:脚本ping接ip是否正常使用[root@lxw2 ~]# vim ping1.sh //新建一个能ping通网络的文件,查看网络能是否正常执行,进入vim界面,写如下脚本内容。
------------------------------------------------------------------------
#!/usr/bin/env bashping -c1 10.3.133.180 //此脚本必须要写上自己的ip地址才可ping通if [ $? -eq 0 ];thenecho "10.3.133.180 is up." //更改 ipelseecho "10.3.133.180 is down!" //更改ipfi
------------------------------------------------------------------------
编写完后:wq! //保存退出
[root@lxw2 ~]# chmod +x ping1.sh //给予ping1.sh 文件可执行权限
[root@lxw2 ~]# ./ping.sh //启动服务
[root@lxw2 ~]# ping 10.3.133.180
PING 10.3.133.181 (10.3.133.180) 56(84) bytes of data.
64 bytes from 10.3.133.180: icmp_seq=1 ttl=64 time=0.371 ms
64 bytes from 10.3.133.180: icmp_seq=2 ttl=64 time=0.463 ms
64 bytes from 10.3.133.180: icmp_seq=3 ttl=64 time=0.464 msCTRL键 +c 退出========================================================================
案例2.脚本使用重定向#!/usr/bin/env bash
[root@lxw2 ~]# vim ping1.sh //继续进入上个脚本文件
------------------------------------------------------------------------
ping -c1 10.3.133.181 &>/dev/null //此处加上追加覆盖if [ $? -eq 0 ];thenecho "10.3.133.181 is up."elseecho "10.3.133.181 is down!" fi------------------------------------------------------------------------
wq! 保存退出
[root@lxw2 ~]# ./ping1.sh //&>/dev/null只看ping结果,不看过程
10.3.133.181 is up.========================================================================
案例3.脚本使用重定向[root@lxw2 ~]# vim ping2.sh
------------------------------------------------------------------------ping -c1 10.3.133.182 &>/dev/nullif [ $? -eq 0 ];thenecho "10.3.133.182 is up." >>up.txtelseecho "10.3.133.182 is down!" >>down.txtfi
------------------------------------------------------------------------
[root@lxw2 ~]# chmod +x ping2.sh //加上执行权限
[root@lxw2 ~]# ./ping2.sh //运行脚本ps:如若写上自己的ip后能ping通,那么即可在root目录下创建up.txt若不通,则创建down.txt
====================================================================
二.输入重定向
标准输入: < 等价 0<
实战演示:
案例1[root@lxw0 ~]# mail alice //给普通用户alice发送邮件
Subject: Hello, Alice. //邮件标题
How are you doing lately? //邮件内容
How's the job? //邮件内容 Did you talk about the object? //邮件内容 ^d 退出并发送CTRL建+d 保存退出 //ps:后续ctrl 键用^ 代替,编程一般都是以^代替ctrl[root@lxw0 ~]# su - alice //切换至alice用户 [alice@lxw0 ~]$ mail //打开邮箱 Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/alice": 2 messages 2 new >N 1 root Mon Sep 7 07:17 22/638 "hello"N 2 root Thu Sep 17 10:15 23/650 "Hello, Alice." & 2 //选择2号邮箱 Message 2: From root@lxw0.localdomain Thu Sep 17 10:15:38 2020 Return-Path: <root@lxw0.localdomain> X-Original-To: alice Delivered-To: alice@lxw0.localdomain Date: Thu, 17 Sep 2020 10:15:38 +0800 To: alice@lxw0.localdomain Subject: Hello, Alice. User-Agent: Heirloom mailx 12.5 7/5/10 Content-Type: text/plain; charset=us-ascii From: root@lxw0.localdomain (root) Status: RHow are you doing lately? //刚刚编写的内容How's the job? //刚刚编写的内容Did you talk about the object? //刚刚编写的内容& q 退出 :按q[root@lxw0 ~]# mail -s "test01" alice < /etc/hosts//输入重定向,来自于文件 ,继续进入alice用户,mail查看新的邮件-----------------------------------------------------------------------
案例2[root@lxw0 ~]# grep 'root' // //在下面输入过滤文字
yang sss sssrootssss.. //回车
yang sss sss'root'ssss..sssrootssss.. //回车sss'root'ssss.. [root@lxw0 ~]# grep 'root' < /etc/passwd //输入重定向模式
'root':x:0:0:'root':/'root':/bin/bash
operator:x:11:0:operator:/'root':/sbin/nologin------------------------------------------------------------------------案例3
[root@lxw2 ~]# dd if=/dev/zero of=/a.txt bs=1M count=2 //输入重定向
记录了2+0 的读入
记录了2+0 的写出
2097152字节(2.1 MB)已复制,0.00167333 秒,1.3 GB/秒
[root@lxw2 ~]# dd </dev/zero >/file2.txt bs=1M count=20 //输出重定向
记录了20+0 的读入
记录了20+0 的写出
20971520字节(21 MB)已复制,0.150229 秒,140 MB/秒dd 执行过程, output 输出文件 , block sise 块大小 ------------------------------------------------------------------------案例4 mysql表结构导入[root@lxw2 ~]# yum -y install mariadb-server mariadb //yum安装mariadb-server mariadb
[root@lxw2 ~]# systemctl start mariadb //启动服务
[root@lxw2 ~]# vim bbs.sql //新建bbs.sql文件,编辑脚本
create database bbs;
create table bbs.t1 (id int);
insert into bbs.t1 values(1);[root@lxw2 ~]# mysql <bbs.sql //重定向
[root@lxw2 ~]# mysql //打开mysql
MariaDB [(none)]> show databases;
MariaDB [(none)]> \q
Bye //有Bye即可 q或者^c退出------------------------------------------------------------------------
案例5 at[root@lxw2 ~]# at now +1 min //at一次性计划任务 now+时间 多久后执行
at> useradd lxw1 //创建lxw1 用户 一分钟后执行
at> <EOT> //^ d 执行退出
job 6 at Thu Sep 17 03:17:00 2020
[root@lxw2 ~]# vim at.txt //新建文件脚本useradd yang100 useradd yang102
[root@lxw2 ~]# at now +1 min <at.txt
job 7 at Thu Sep 17 03:21:00 2020[root@lxw2 ~]# id lxw1
uid=1005(lxw1) gid=1005(lxw1) 组=1005(lxw1)
[root@lxw2 ~]# id lxw2
uid=1006(lxw2) gid=1006(lxw2) 组=1006(lxw2)
[root@lxw2 ~]# id lxw3
uid=1007(lxw3) gid=1007(lxw3) 组=1007(lxw3)-----------------------------------------------------------------------综合案例 1: 利用重定向建立多行文件[root@lxw2 ~]# echo '111' >d.txt //echo 把‘111’ 追加至d.txt文本内容中
[root@lxw2 ~]# cat d.txt //cat 查看文本内容
111综合案例 2
[root@lxw2 ~]# vim create_file.shcat >file200.txt <<EOF 111222 333 yyy cccEOF //不能有空格,格式要求较为严格
[root@lxw2 ~]# bash create_file.sh
[root@lxw2 ~]# cat create_file.sh
cat >file200.txt <<EOF 111222 333 yyy cccEOF-----------------------------------------------------------------------
综合案例3: 脚本中利用重定向打印消息[root@lxw2 ~]# vim lxw1.sh
cat <<-EOF
+---------------------------------------+
| 虚拟机基本管理 v4.0 |
| |
| by tianyun |
| 1. 安装KVM |
| 2. 安装或重置CentOS-6.8 |
| 3. 安装或重置CentOS-7.3 |
| 4. 安装或重置RHEL-6.4 |
| 5. 安装或重置Windows-7 |
| 6. 删除所有虚拟机 |
| q. 退出管理程序 |
| |
| |
+---------------------------------------+EOF[root@lxw2 ~]# cat lxw1.sh //查看vim内容综合案例 4 [root@lxw2 ~]# ls &>/dev/null; date &>/dev/null //等价与
[root@lxw2 ~]# (while :; do date; sleep 2; done) & //在后台运行,但输出依然在前台终端 //退出要执行kill -9 11433【进程编号】
ps: 此时会不断的显示时进程 ,输入命令可持续换号输入
-----------------------------------------------------------------------------------
[root@lxw2 ~]# (while :; do date; sleep 2; done) &
[3] 109854
[2] 已终止 ( while :; dodate; sleep 2;
done )
[root@lxw2 ~]# 2020年 09月 17日 星期四 03:56:54 CST
[root@lxw2 ~]# 2020年 09月 17日 星期四 03:57:06 CST
'jobs' //输入jobs 查看进程为【3】号进程
[3]+ 运行中 ( while :; dodate; sleep 2;
done ) &
[root@lxw2 ~]# 2020年 09月 17日 星期四 03:57:18 CST
'kill'2020年 09月 17日 星期四 03:57:20 CST //输入kill ps输入慢也没关系,跳转下一行继续输入,只要命令格式对,就可以进行进程终止
' '2020年 09月 17日 星期四 03:57:22 CST //必须要有空格,否则命令无法执行
'%'2020年 09月 17日 星期四 03:57:24 CST //百分号加3号进程
2020年 09月 17日 星期四 03:57:26 CST
'3' //回车即可
[root@lxw2 ~]#
----------------------------------------------------------------------------------------
命令先输入jobs 回车 查看进程编号 , 然后在输入进程编号 kill %1 回车 即可,记得空格符号必须都不能输错,否则命令无效 &> && & ||
混合输出 逻辑与[命令1执行成功 ,才能执行命令2] 在命令结尾,代表放后台执行 命令一执行失败,则命令2可执行cd /tatat &>/dev/null && touch a.txt // cd到/tatat会失败,文件a.txt也不会创建成功
cd /tmp &>/dev/null || touch a.txt // cd到/tmp成功,文件a.txt不会创建成功cd /tatat &>/dev/null || touch a.txt //cd到/tatat会失败,会在root下面创建a.txt
cd /tatat &>/dev/null && touch a.txt //cd到/tatat会失败,创建a.txt也会失败,还是在root下touch a.txt || cd /tmp && touch b.txt // 创建a.txt会成功,但是不会cd到/tmp下面,还是在root下,b.txt创建成功
(touch a.txt || cd /tmp )&& touch b.txt // 创建a.txt 然后cd/tmp下 再创建b.txttouch a.txt && cd /tmp || touch b.txt // 会在root下创建a.txt,然后cd到/tmp下,b.txt创建失败
touch a.txt && cd /tmpppppp || touch b.txt // 会在root下创建a.txt,b.txt 然后cd到/tmpppppp失败,
====================================================================================
三.进程管道Piping
用法:command1 | command2 |command3 | //进程管道
例: ps -ef | head //head 看默认进程前十行内容
| 管道符,用户后续输出命令
[root@lxw2 ~]# ps aux |grep 'sshd' //查看进程 | 过滤sshd
[root@lxw2 ~]# rpm -qa |grep 'httpd' //查找所有软件 | 过滤httpd的包
[root@lxw2 ~]# yum list |grep 'httpd' //列出所有软件 | 过滤httpd的包案例1:将/etc/passwd中的用户按UID大小排序
[root@lxw2 ~]# sort -t":" -k3 -n /etc/passwd //以: 分隔,将第三列按字数升序 -k3 第三列排序, -n按数值
[root@lxw2 ~]# sort -t":" -k3 -n /etc/passwd -r //逆序
[root@lxw2 ~]# sort -t":" -k3 -n /etc/passwd |head -10 //指定字段分隔符--field-separator -k 指定那一列排序 -n 按数值案例2: 统计最占cpu的5个进程
[root@lxw2 ~]# ps aux --sort=-%cpu |head -6 //显示cpu 前6行案例3: 统计当前/etc/passwd中用户使用的shell类型
思路:取出第七列(shell) | 排序(把相同归类)| 去重
[root@lxw2 ~]# awk -F: '{print $7}' /etc/passwd //print $7 打印文件第七列 / -F 指定列和列的分隔符 $num 打印那一列
[root@lxw2 ~]# awk -F: '{print $7}' /etc/passwd |sort |uniq //
/bin/bash
/bin/sync
/sbin/halt
/sbin/nologin
/sbin/shutdownuniq 去重 //sort 排序 // -c统计数量 uniq去重只能对相邻并且相同的行才能去重,相同但不相邻的行不能去重,所以要用sort 先排序 /$7打印第七列 , -F":" 分隔符案例4: 统计网站的访问情况 top 20 思路: 打印所有访问的连接 | 过滤访问网站的连接 | 打印用户的IP | 排序 | 去重
[root@lxw2 ~]# yum -y install httpd //安装httpd 服务
[root@lxw2 ~]# systemctl start httpd //启动httpd 启动【start】
systemctl stop firewalld //关闭防火墙浏览器输入ip 10.3.133.182,即可查看
[root@lxw2 ~] ss -an |grep :80 |awk -F":" '{print $8}' |sort |uniq -c |sort -k1 -rn |head -n 20 //统计网站访问情况案例5: 打印当前所有IP
[root@lxw2 ~]# ip addr |grep 'inet' |awk '{print $2}' |awk -F"/" '{print $1}' //查看当前ip 全称 ip addr list 过滤ip所在行 |打印第二列【默认空格为分隔符】 | 去除ip后的/
127.0.0.1
::1
10.3.133.182[root@lxw2 ~]# df -P |grep '/$' |awk '{print $5}' |awk -F"%" '{print $1}' //打印根分区已用空间的百分比(仅打印数字)
11[root@lxw2 ~]# ip addr |grep 'inet ' |tee ip.txt |awk -F"/" '{print $1}' |awk '{print $2}' // //把前面产生的数据传输到文件里面
127.0.0.1
10.3.133.182
===================================================================
四.参数传递
案例1
[root@lxw2 ~]# touch /home/file{1..5} //创建file1-5文件
[root@lxw2 ~]# vim files.txt //编辑一个新的文件 写上刚刚创建文件的路径 set list 显示行特殊符号
[root@lxw2 ~]# cat files.txt |xargs ls -l //xargs 默认把前面的输出放后面去使用
[root@lxw2 ~]# cat files.txt |xargs rm -rvf //xargs 参数传递 //删除file1至file5的文件
已删除"/home/file1"
已删除"/home/file2"
已删除"/home/file3"
已删除"/home/file4"
已删除"/home/file5"案例2
[root@lxw2 ~]# touch /home/file{1..5}
[root@lxw2 ~]# cat files.txt |xargs -I {} ls -l {} // -I 把前面的参数先暂存至{}里面
[root@lxw2 ~]# cat files.txt |xargs -I {} cp -rvf {} /tmp //可以理解为前边的输出暂存至{}
[root@lxw2 ~]# find /etc -name "*ifcfg*" |xargs -I {} cp -rf {} /tmp //查找*ifcfg*