Linux重定向管道

一,重定向

1,什么是重定向?

Linux重定向是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作。

输出重定向的示例://默认输出到终端,可以指定到某个文件

输出重定向。
当我们执行命令时,命令的结果会输出到屏幕上。
希望后续再查看输出时,可以使用输出重定向。
1    默认输出位置:屏幕
date                          //默认输出结果到屏幕上。
2   指定输出位置:文档。
date > date.txt        //通过本次学习,输出到指定文件。
tty                //查看当前终端,理解输出到屏幕。

2,标准输入、标准输出、标准错误输出(FD(file descriptor/文件描述符/句柄)简介)

file descriptors (FD,文件描述符 或 Process I/O channels):
进程使用文件描述符来管理打开的文件
[root@tianyun ~]# ls /proc/$$/fd
0 1 2 3 4
0, 1, and 2, known as standard input, standard output, and standard error

简单理解就是0表示键盘的标准输入,1表示标准的输出,2表示标准错误输出,其他代表普通文件的输出

fd就是就是一种软连接,不同的数值代表不同含义

FD开启示例:

目的:通过vim查看一下文件描述

1 通过VIM打开一个新文件。
vim 1.txt
2 通过其他终端,查询VIM程序。
ps  aux| grep vim
3 在/proc中查询VIM进程ID.
ll /proc/PID/fd  就能看到文件的调用。

[root@localhost ~]# ll /proc/5606/fd
总用量 0
lrwx------. 1 root root 64 10月 10 07:37 0 -> /dev/pts/2
lrwx------. 1 root root 64 10月 10 07:37 1 -> /dev/pts/2
lrwx------. 1 root root 64 10月 10 07:37 2 -> /dev/pts/2
lrwx------. 1 root root 64 10月 10 07:37 3 -> /root/.1.txt.swp

看到的0124就是FD,程序通过描述符访问文件,可以是常规文件,也可以是设备文件。

3,输出重定向案例><

3.1 输出重定向及综合案例

简介:

输出重定向 (覆盖,追加)
正确输出: 1> 1>> 等价于 > >>
错误输出: 2> 2>>

案例1:输出重定向(覆盖):>

[root@tianyun ~]# date 1> date.txt


案例2:输出重定向(追加):>>

[root@tianyun ~]# date >> date.txt

案例3:错误输出重定向:2>

[root@tianyun ~]# ls /home/ /aaaaaaaaa >list.txt
ls: 无法访问/aaaaaaaaa: 没有那个文件或目录
[root@tianyun ~]# ls /home/ /aaaaaaaaa >list.txt 2>error.txt //重定向到不同的位置

案例4: 正确和错误都输入到相同位置:&>

[root@tianyun ~]# ls /home/ /aaaaaaaaa      &>     list.txt //混合输出


案例5: 正确和错误都输入到相同位置:2>&1

[root@tianyun ~]# ls /home/ /aaaaaaaaa >list.txt 2>&1 //重定向到相同的位置 


案例6:重定向到空设备/dev/null

[root@tianyun ~]# ls /home/ /aaaaaaaaa >list.txt 2>/dev/null //空设备,即将产生的输出丢掉
[root@tianyun ~]# ls /home/ /aaaaaaaaa &>/dev/null //空设备,即将产生的输出丢掉

案例7:脚本中使用重定向

[root@tianyun ~]# vim ping.sh
ping -c1 172.16.120.254 &>/dev/null
if [ $? -eq 0 ];then
echo "up.."
else
echo "down.."
fi
[root@tianyun ~]# bash ping.sh

案例8:脚本中使用重定向

# vim ping2.sh
ping -c1 172.16.120.254 &>/dev/null
if [ $? -eq 0 ];then
echo "172.16.120.254 up.." >> /up.txt
else
echo "172.16.120.254 down.." >> /down.txt
fi
# bash ping2.sh

3.2 输入重定向及综合案例

简介:

标准输入: < 等价于0<

案例1:重定向发送邮件

1,观察默认发送邮件的过程

[root@tianyun ~]# mail -s "ssss" alice //没有改变输入的方向,默认键盘
111
222
333
.    //点代表邮件创建结束。
[root@tianyun ~]# su - alice
[alice@tianyun ~]$ mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/alice": 1 message 1 new
>N 1 root@tianyun.local Mon Oct 29 14:09 18/657 "ssss"
&
按邮件编号:1.即可看邮件。

2,使用重定向快速创建邮件

如果已经有了现成的邮件内容呢,如何快速输入邮件内容。
就可以用重定向创建邮件!!!
[root@tianyun ~]# mail -s "test01" alice < /mail.txt
//输入重定向,来自于文件mail.txt是通用邮件。
    邮件范例
        Dear  ,
Good day.
Glad to contact with you.
Enclosed is purchse order for your company, please kindly check it.
Any questions please kindly contact with me.

Thanks & Best Regards,

案例2:在文件中查找字段

[root@tianyun ~]# grep 'root' //没有改变输入的方向,默认键盘,此时等待输入...
输入些不带root的词,再输入些带root的词观察结果。
yang sss
sssrootssss..
sssrootssss..

[root@tianyun ~]# grep 'root' < /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
这个方法比较纯理论。

案例3:通过dd命令理解输入输出重定向(了解)

先理解一个命令。dd 快速创建文件。 if输出  of输入 bs大小 count计数
[root@tianyun ~]# dd if=/dev/zero of=/file1.txt bs=1M count=2
ll -h /file1.txt
可以看到文件大小。
[root@tianyun ~]# dd </dev/zero >/file2.txt bs=1M count=20

案例4:mysql表结构导入(了解)(免操作)

[root@tianyun ~]# mysql -uroot -p123 < bbs.sql
该案例,需要mysql数据库技术的职称。了解一下即可。

案例5:自动创建任务计划at(了解)

1,先理解at任务计划原理

[root@tianyun ~]# at now +5 min
at> useradd yang99
at> <EOT>            //ctrl+D结束
job 1 at 2015-06-09 11:57

2,通过重定向,自动创建任务计划

[root@tianyun ~]# vim at.txt
sudo useradd yang100
sudo useradd yang102
[root@tianyun ~]# at now +2 min < at.txt
job 2 at 2015-06-09 11:55

3.3 综合案例

案例1:利用输入重定向(段落标记EOF)建立多行的文件

[root@tianyun ~]# cat >file4 <<EOF
> 111
> 222
> 333
> EOF
[root@tianyun ~]# cat file4
111
222
333

案例2:脚本中利用重定向打印消息(了解,类似案例1)


使用<<-EOF结束标记。
-是使脚本识别tab缩进。

[root@tianyun ~]# vim message.sh
#!/usr/bin/bash
cat <<-EOF
+------------------------------------------------+
| |
| ====================== |
| 虚拟机基本管理centos |
| by tianyun |
| ====================== |
| 1. 安装虚拟机 |
| 2. 重置所有Linux虚拟机 |
| 3. 重置Windows虚拟机 |
| 4. 重置Windows虚拟机 [完全] |
| 5. 重置指定的虚拟机 |
| q. 退出管理程序 |
| |
+------------------------------------------------+
EOF

输出重定向技巧(了解)

请思考两条指令能否将结果一起输出去到垃圾桶。
[root@tianyun ~]# ls; date &>/dev/null
请观察,输出的结果的原因,
前者在屏幕上,后者去了垃圾桶。
怎么解决呢?
[root@tianyun ~]# ls &>/dev/null; date &>/dev/null

是不是可以这样做,()括起来作为整体。
[root@tianyun ~]# (ls; date) &>/dev/null

subshell(了解) 

 ==当前shell中执行==

[root@tianyun ~]# cd /boot; ls
config-3.10.0-514.el7.x86_64
efi
grub
grub2
initramfs-0-rescue-a024cb8d031d445580a7b5aaf92a9ca0.img
initramfs-3.10.0-514.el7.x86_64.img
initrd-plymouth.img
symvers-3.10.0-514.el7.x86_64.gz
System.map-3.10.0-514.el7.x86_64
vmlinuz-0-rescue-a024cb8d031d445580a7b5aaf92a9ca0
vmlinuz-3.10.0-514.el7.x86_64
[root@tianyun boot]#
注意观看,当前目录。发生了改变 

 ==在subshell中执行==     

 [root@tianyun boot]# cd            //先回到家目录
小括号,是打开了一个新的shell解释了命令,执行完毕后又关闭了。
我们把这一现象称作子shell。
[root@tianyun ~]# (cd /boot; ls)
config-3.10.0-514.el7.x86_64
efi
grub
grub2
再次显示出了目录中的内容。请观察目录是否改变。
[root@tianyun ~]#
如果不希望某些命令的执行对当前shell环境产生影响,请在subshell中执行!

关于权限掩码的另一个小案例。理解subshell
[root@tianyun ~]# (umask 777; touch file8888)
[root@tianyun ~]# ll file8888
---------- 1 root root 0 Apr 12 22:11 file8888
[root@tianyun ~]# umask
0022

二,管道

1,管道 |

1.1 进程管道Piping

1.1.1 简介

重定向和管道的区别在于,输出到文件和程序。
• Use redirection characters to control output to files.
• Use piping to control output to other programs.

重定向和管道的符号对比。重定向输出到各种文件。管道是到一个程序。

重定向:
files: > 2>     file1.txt     
    /dev/pts/2     
    /dev/tty1
    /dev/null     
    /dev/sda
管道:
programs1    |    programs2
结论:如果你想把结果给另外一个程序,就请使用管道。
    tty
        tty(终端设备的统称):
tty一词源于Teletypes,或teletypewriters,原来指的是电传打字机,是通过串行线用打印机键盘通过阅读和发送信息的东西,后来这东西被键盘和显示器取代,所以现在叫终端比较合适。
    pts
        pty(虚拟终端):
但是假如我们远程telnet到主机或使用xterm时不也需要一个终端交互么?是的,这就是虚拟终端

1.1.2 语法

进程管道
用法:command1 | command2 |command3 |...

1.1.3 示例

[root@tianyun ~]# ll /dev/ |less
[root@tianyun ~]# ps aux |grep 'sshd'

1.1.4 扩展案例(了解)

案例1:排序和管道

将/etc/passwd中的用户按UID大小排序
1  首先理解一个新命令。sort排序。
[root@tianyun ~]# sort -t":" -k3 -n /etc/passwd //以: 分隔,将第三列按字数升序
[root@tianyun ~]# sort -t":" -k3 -n /etc/passwd -r //逆序
-t 指定字段分隔符--field-separator
-k 指定列
-n 按数值
-r 倒序

2 使用管道和head查看前几行。
[root@tianyun ~]# sort -t":" -k3 -n /etc/passwd |head

案例2:排序和头部

统计出最占CPU的5个进程
[root@tianyun ~]# ps aux --sort=-%cpu |head -6

案例3:取值,排序和去重

统计当前/etc/passwd中用户使用的shell类型
思路:取出第七列(shell) | 排序(把相同归类)| 去重
[root@tianyun ~]# awk -F: '{print $7}' /etc/passwd
[root@tianyun ~]# awk -F: '{print $7}' /etc/passwd |sort
[root@tianyun ~]# awk -F: '{print $7}' /etc/passwd |sort |uniq
[root@tianyun ~]# awk -F: '{print $7}' /etc/passwd |sort |uniq -c
131 /bin/bash
1 /bin/sync
1 /sbin/halt
63 /sbin/nologin
1 /sbin/shutdown

-F: 指定字段分隔符
$7 第七个字段
uniq 去重
-c  统计

案例4:取值,排序和去重

统计网站的访问情况 top 20
1.该实验,需要先部署网站,再需要人访问网站。
yum install -y httpd            //安装网站
systemctl start httpd    //启动网站
ifconfig                    //查看自己的IP
setenforce 0                    //关闭防火墙
systemctl stop firewalld    //关闭防火墙2
2。使用管道过滤出访问量前20名用户。
思路: 打印所有访问的连接 | 过滤访问网站的连接 | 打印用户的IP | 排序 | 去重

[root@tianyun ~]# ss -an |grep :80 |awk -F":" '{print $8}' |sort |uniq -c
4334 192.168.0.66
1338 192.168.10.11
1482 192.168.10.125
44 192.168.10.183
3035 192.168.10.213
375 192.168.10.35
362 192.168.10.39

再看看前20用户。
[root@tianyun ~]# ss -an |grep :80 |awk -F":" '{print $8}' |sort |uniq -c |sort -k1 -rn |head -n 20

案例5:打印当前所有IP

[root@tianyun ~]# ip addr |grep 'inet ' |awk '{print $2}' |awk -F"/" '{print $1}'
127.0.0.1
192.168.2.115
扩展内容:了解awk sed grep sort uniq less more xargs

1.2 tee管道

1.2.1 简介

    之前的课程,输出的内容给某一个程序。同时输出到别的地方可以吗?比如文件中去。
下面就是管道的分支,支流。一个命令可以有多个管道,通常我们看到的是最后的结果。
如果想看到其中一段的内容,请使用tee。

1.2.2 案例

[root@tianyun ~]# ip addr |grep 'inet ' |tee ip.txt |awk -F"/" '{print $1}' |awk '{print $2}'
127.0.0.1
172.16.60.1

[root@tianyun ~]# cat ip.txt
inet 127.0.0.1/8 scope host lo
inet 172.16.60.1/24 brd 172.16.60.255 scope global eth0

想追加到某个文件,使用-a
[root@tianyun ~]# ip addr |grep 'inet ' |tee -a ip.txt |awk -F"/" '{print $1}' |awk '{print $2}'
127.0.0.1
172.16.60.1

[root@localhost ~]# date
2017年 9月 04日 星期三 08:18:15 CST
[root@localhost ~]# date > 1.txt
[root@localhost ~]# date | tee 1.txt
2017年 9月 04日 星期三 08:18:24 CST
[root@localhost ~]# cat 1.txt
2017年 9月 04日 星期三 08:18:24 CST
[root@localhost ~]#

2,参数传递Xargs

ls cp rm一些特殊命令,只接受命令行参数中指定的处理内容,不从标准输入中获取处理内容。
xargs:

案例1:

1 环境准备,准备一些文件。
[root@localhost ~]# touch /home/file{1..5}

2 将文件名写入一个文本中。作为输出结果。(假设的环境)
[root@localhost ~]# vim files.txt
/home/file1
/home/file2
/home/file3
/home/file4
/home/file5

3 使用管道,失败。
[root@localhost ~]# cat files.txt |ls -l(在Centos7以后的版本这个是可以执行的)
[root@localhost ~]# cat files.txt |rm -rvf

cont.
4.貌似之前的不行。下面加上xargs
[root@localhost ~]# cat files.txt |xargs ls -l
-rw-r--r--. 1 root root 0 Mar 11 10:35 /home/file1
-rw-r--r--. 1 root root 0 Mar 11 10:35 /home/file2
-rw-r--r--. 1 root root 0 Mar 11 10:35 /home/file4
-rw-r--r--. 1 root root 0 Mar 11 10:35 /home/file5

[root@localhost ~]# cat files.txt |xargs rm -rvf
removed ‘/home/file1’
removed ‘/home/file2’
removed ‘/home/file4’
removed ‘/home/file5’

案例2:xargs  -I 指定输出标记

1 准备一些环境。创建多个文件。
[root@localhost ~]# touch /home/file{1..5}

2 加入-I标记。进行查看。
[root@localhost ~]# cat files.txt |xargs -I {} ls -l {}
-rw-r--r--. 1 root root 0 Mar 11 10:40 /home/file1
-rw-r--r--. 1 root root 0 Mar 11 10:40 /home/file2
-rw-r--r--. 1 root root 0 Mar 11 10:40 /home/file4
-rw-r--r--. 1 root root 0 Mar 11 10:40 /home/file5
3 加入-I标记。进行复制。
[root@localhost ~]# cat files.txt |xargs -I {} cp -rvf {} /tmp
‘/home/file1’ -> ‘/tmp/file1’
‘/home/file2’ -> ‘/tmp/file2’
‘/home/file4’ -> ‘/tmp/file4’
‘/home/file5’ -> ‘/tmp/file5’
4 加入-I标记,可以使用字符代替。
[root@localhost ~]# cat files.txt |xargs -I XULEI cp -rvf XULEI /var/tmp
‘/home/file1’ -> ‘/var/tmp/file1’
‘/home/file2’ -> ‘/var/tmp/file2’
‘/home/file4’ -> ‘/var/tmp/file4’
‘/home/file5’ -> ‘/var/tmp/file5’

 加-i 参数直接用 {}就能代替管道之前的标准输出的内容;
 加 -I 参数 需要事先指定替换字符

案例3:

[root@localhost ~]# find /etc -iname "*ifcfg*" |xargs -I {} cp -rf {} /tmp
-name :按照文件名查找文件(精确查找);-iname不区分文件名大小写进行查找(用法:find -iname test.c)

3,匿名和命名管道(了解)

两者的区别:

1、对文件系统来说,匿名管道是不可见的,它的作用仅限于在父进程和子进程两个进程间进行通信。而命名管道是一个可见的文件

2、pipe只能是两个具有公共祖先的进程间进行通信,而FIFO可以用于任何两个进程之间的通信,不管这两个进程是不是父子进程,也不管这两个进程之间有没有关系。

3、pipe创建出来的管道没有名字,而FIFO是通过唯一路径来标识唯一的命名管道。

3.1 匿名管道:

匿名管道就是上面使用的“|”,其实就是把管道一端的处理结果交到管道的另一端来处理

例如:ps aux | less

3.2 命名管道:

1. 创建命名管道
mkfifo a
touch b
2 观察命名管道文件与普通文件的不同。
ll  a   b
3 查看命名管道的文件类型
file   a
fifo  name  pipe
4 传统文件和管道文件不同之处,匿名管道使用完毕内容消失。
而命名管道文件使用后不会消失,并且可以被其他程序读取。
5 访问FIFO文件
同样有两种方式访问FIFO文件。
命令行方式。首先用cat命令读取刚才创建的FIFO文件:
cat <  a
这个时候,cat命令将一直挂起,直到终端或者有数据发送到FIFO中。
6 . 然后尝试向FIFO中写数据(在另外一个终端执行这个命令)
echo "FIFO test" > a
这个时候cat将会输出内容。







  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值