码迷,mamicode.com
首页 > 系统相关 > 详细

linux中的重定向和管道的使用方法

时间:2016-07-31 22:40:23      阅读:761      评论:0      收藏:0      [点我收藏+]

标签:linux   重定向   管道   

一个程序运行就必须要有指令和数据或者说数据结构和算法。程序处理的数据来源和处理后存放在哪,是程序员必须要考虑额问题。每个程序都有读入数据和输出数据的需求,但是为了便捷,程序允许缺省输入和输出,也就是使用默认的输入输出。一般称之为标准输入和标准输出。

对于用户来说,访问文件是通过文件名来进行的,但对于内核来说则是一个非零整数,这个数字叫做文件描述符(file descriptor,fd),打开已存在的文件或新建一个文件时,内核会返回一个文件描述符,读写文件也需要使用文件描述符来指定带读写的文件。

注意:文件描述符和inode号是有区别的,inode号是文件系统创建时就已经确定的,当创建一个新的文件或目录时,系统从inode表中选出一个空闲的inode号来唯一标识这个文件,并将文件的数据块位置存在inode里,当许多用户对同一个文件进行操作时,内核将为每位用户分配一个文件描述符,即一个文件可能对应多个文件描述符。

具体的Linux文件系统原理可以参考:

https://www.ibm.com/developerworks/cn/linux/l-linux-filesystem/

https://akaedu.github.io/book/ch29s03.html

https://www.ibm.com/developerworks/cn/linux/l-vfs/  

标准输入的文件描述符是0,标准输出是1,标准错误输出是2

I/O重定向:改变标准位置

重定向支持的操作符有三种:

>:标准输出重定向,可以输出到指定的文件,但会覆盖文件内容,>>则是在文件内容的后面追加新内容

2>:重定向错误到文件,和>类似,2>>表示追加

<:输出重定向

set -C:禁止重定向到文件时覆盖已存在的文件,只对当前shell有效

set +C:撤销禁用覆盖

[root@localhost testdir]# ajf 2> afi
[root@localhost testdir]# set -C
[root@localhost testdir]# ajf 2> afi
-bash: afi: cannot overwrite existing file
[root@localhost testdir]# ajf 2> a
[root@localhost testdir]# ajf 2> a
-bash: a: cannot overwrite existing file

可以将标准输出和标准错误输出分别重定向到不同文件

[root@localhost testdir]# ll
total 8
-rw-r--r--. 1 root root 32 Jul 31 09:50 
a-rw-r--r--. 1 root root 32 Jul 31 09:48 afi
[root@localhost testdir]# ll a afi mage > f1 2> f2
[root@localhost testdir]# cat f1 
-rw-r--r--. 1 root root 32 Jul 31 09:50 a
-rw-r--r--. 1 root root 32 Jul 31 09:48 afi
[root@localhost testdir]# cat f2
ls: cannot access mage: No such file or directory

如果要将输出和错误同时写入一个文件,也可以用更简便的写法

[root@localhost testdir]# cat f1 f2 f3 &> f4
[root@localhost testdir]# cat f4
-rw-r--r--. 1 root root 32 Jul 31 09:50 a
-rw-r--r--. 1 root root 32 Jul 31 09:48 afi
ls: cannot access mage: No such file or directory
cat: f3: No such file or directory

或者用下面的老写法

[root@localhost testdir]# cat f1 f2 f3 > f5 2>&1
[root@localhost testdir]# cat f5
-rw-r--r--. 1 root root 32 Jul 31 09:50 a
-rw-r--r--. 1 root root 32 Jul 31 09:48 afi
ls: cannot access mage: No such file or directory
cat: f3: No such file or directory

同理,&>>表示追加

[root@localhost testdir]# cat f1 f2 f3 >> f5 2>&1
[root@localhost testdir]# cat f1 f2 f3 &>> f4

也可以合并多个命令的输出

[root@localhost testdir]# (cat f4;ls ) > f3
[root@localhost testdir]# cat f3
-rw-r--r--. 1 root root 32 Jul 31 09:50 a
-rw-r--r--. 1 root root 32 Jul 31 09:48 afi
ls: cannot access mage: No such file or directory
cat: f3: No such file or directory
-rw-r--r--. 1 root root 32 Jul 31 09:50 a
-rw-r--r--. 1 root root 32 Jul 31 09:48 afi
ls: cannot access mage: No such file or directory
cat: f3: No such file or directory
a
afi
f1
f2
f3
f4
f5

可以看到,先创建了重定向的文件,在执行前面的内容,然后将输出写入文件

[root@localhost testdir]# rm -rf *
[root@localhost testdir]# ll        #此时没有文件
total 0
[root@localhost testdir]# ll > file1      #ll当前空目录并重定向到file1
[root@localhost testdir]# cat file1      #然而file1的内容不为空,显示了它自己的信息,并且它的大小是0
total 0
-rw-r--r--. 1 root root 0 Jul 31 10:05 file1

输入重定向:<

使用<可以配合cat创建并写入文件

[root@localhost testdir]# cat <<eof
> aaa
> bbb
> ccc
> 
> eof
aaa
bbb
ccc

必须是<<,eof为定义的结束标志,可以是任意字符,也可以将输出重定向到文件

[root@localhost testdir]# cat >> aaa <<eof
> welcome to the new world!
> eof
[root@localhost testdir]# cat aaa
welcome to the new world!

tr命令:转换或输出字符串

语法:tr [OPTIONS] set1 [set2]

tr复制标准输入到标准输出,并且执行转化、挤压重复字符串、删除字符串、先删除然后将输出再挤压重复的字符

-c,-C,--complement 取字符集的子集

-d,--delete 删除属于第一字符集的字符

-s,--squeeze-repeats 把连续且重复的字符用一个表示

-t,--truncate-set1 将第一个字符集对应的字符转化为第二个字符集对应的字符

 mail 发送那个信息:

mail -s NAME WHO

管道:

将命令1的标准输出发送给命令2的标准输入,以此类推

标准错误默认不能通过管道传输,可用2>&1或|&实现

最后一个命令会在当前shell进程的子shell进程中执行

重定向到多个目标:tee

[root@localhost testdir]# ls |tee f1 
aaa
asd
file1
[root@localhost testdir]# cat f1
aaa
asd
file1

tee会将命令的输出重定向到标准输出和一个文件

练习:

1、将/etc/issue文件的内容转换为大写保存到/tmp/issue.out文件中

[root@localhost ~]# tr [a-z] [A-Z] < /etc/issue > /tmp/issue.out 
[root@localhost ~]# cat /tmp/issue.out 
\S
KERNEL \R ON AN \M

或者

[root@localhost ~]# tr ‘[:lower:]‘ ‘[:upper:]‘ < /etc/issue > /tmp/issue.out.bak 
[root@localhost ~]# cat /tmp/issue.out.bak 
\S
KERNEL \R ON AN \M

2、将当前系统登录用户信息转换为大写后保存至/tmp/who.out文件中

[root@localhost ~]# w |tr ‘[:lower:]‘ ‘[:upper:]‘ > /tmp/who.out 
[root@localhost ~]# cat /tmp/who.out 
 10:54:38 UP  1:23,  2 USERS,  LOAD AVERAGE: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
ROOT     PTS/0    10.1.250.91      09:31    6.00S  0.49S  0.02S W
ROOT     PTS/1    10.1.250.91      09:36   21:10   0.29S  0.26S INFO TR

3、一个Linux用户给root发邮件,邮件标题为help,正文是:Hello,I am 用户名,the system version is here,please help me to check it ,thanks!

操作系统信息

[nieda@localhost ~]$ mail -s "help" root <<eof
> Hello,I am `whoami`,the system version is here,please help me to check it,thanks!
> `uname -or`
> eof
[nieda@localhost ~]$
[root@localhost ~]# mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help
>N  8 nieda                 Sun Jul 31 11:01  19/716   "help"
& 8
Message  8:
From nieda@localhost.localdomain  Sun Jul 31 11:01:36 2016
Return-Path: <nieda@localhost.localdomain>
X-Original-To: root
Delivered-To: root@localhost.localdomain
Date: Sun, 31 Jul 2016 11:01:36 +0800
To: root@localhost.localdomain
Subject: help
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: nieda@localhost.localdomain (nieda)
Status: R

Hello,I am nieda,the system version is here,please help me to check it,thanks!
3.10.0-327.el7.x86_64 GNU/Linux

其中`whoami`可以用$USER替换,uname -ar可能信息不全,可以用uname -a或者cat /etc/centos-release

也可以将要发送的信息先写在一个文件里,然后在发送,但是要发送的文件里只能是纯文本,不能有变量和命令。

4、将/root/下文件列表,显示成一行,文件名之间用空格隔开

[root@localhost ~]# ls /root/ |tr ‘\n‘ ‘ ‘
anaconda-ks.cfg Desktop Documents Downloads f1 file1 initial-setup-ks.cfg Music Pictures Public Templates Videos [root@localhost ~]#

5、file1文件的内容为“1 2 3 4 5 6 7 8 9 10”计算出所有数字的总和

[root@localhost testdir]# cat file 
1 2 3 4 5 6 7 8 9 10
[root@localhost testdir]# cat file |tr ‘ ‘ ‘+‘|bc
55

6、删除wndows文本文件中的‘^M’字符

[root@localhost testdir]# cat windows.txt 
a^M
bhello^MaMDZZ
MDZZ[root@localhost testdir]# file windows.txt 
windows.txt: ASCII text, with CRLF line terminators
[root@localhost testdir]# hexdump windows.txt 
0000000 5e61 0d4d 620a 6568 6c6c 5e6f 614d 444d
0000010 5a5a 0a0d 444d 5a5a                    
0000018

可以看到^M的二进制是61

[root@localhost testdir]# cat windows.txt |tr -d ^M
a
bhello
aDZZ

7、处理字符串“xt.,| 1 jr#!$mn 2 c*/fe 3 uz 4”,只保留其中的数字和空格

[root@localhost testdir]# cat a
xt.,| 1 jr#!$mn 2 c*/fe 3 uz 4
[root@localhost testdir]# tr -c -d ‘[:digit:][:space:]‘ < a
 1  2  3  4

8、将PATH变量每个目录显示在独立的一行

[root@localhost testdir]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost testdir]# echo $PATH|tr ‘:‘ ‘\n‘
/usr/lib64/qt-3.3/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/root/bin

9、删除指定文件的空行

[root@localhost testdir]# cat a
hello,wang

I am root

I have some questions about the linux command need your help

if you have time,call me please!
eof
[root@localhost testdir]# tr -s ‘\n‘ < a
hello,wang
I am root
I have some questions about the linux command need your help
if you have time,call me please!
eof
[root@localhost testdir]#

10、将文件中每个单词(字母)显示在独立的一行,并无空行

[root@localhost testdir]# tr ‘[:blank:][:punct:]‘ ‘\n‘ < word |tr -s ‘\n‘
hello
this
is
the
CCTV
welcome
to
listen
our
news
you
can
look
the
news
happend
everywhere
at
once


linux中的重定向和管道的使用方法

标签:linux   重定向   管道   

原文地址:http://11551196.blog.51cto.com/11541196/1832495

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!