linux数据流重定向和管道

简介: 1、标准输入、输出、错误 在执行一个指令的时候,这个指令可能会由文件读入资料,然后经过处理,再将数据输出到屏幕上。一般来说,要执行一个指令,其流程是这样的: 1、标准输入(stdin):代码为0,使用< 或 > 3、标准错误输出(stderr):代码...

1、标准输入、输出、错误

在执行一个指令的时候,这个指令可能会由文件读入资料,然后经过处理,再将数据输出到屏幕上。一般来说,要执行一个指令,其流程是这样的:


1、标准输入(stdin):代码为0,使用< 或 << 

2、 标准输出(stdout):代码为1,使用>或>>

3、标准错误输出(stderr):代码为2,使用2>或2>>

例如,我们想把/目录下的所有文件用:ls -l 命令列出,但是不显示在桌面,而是显示在一个新建的文件里,我们可以执行如下命令:

[root@localhost /]#  ls -l > /newroot

[root@localhost /]# cat newroot 
total 142
drwxr-xr-x   2 root root  4096 Jan 21 02:33 bin
drwxr-xr-x   4 root root  1024 Jan 21 06:15 boot
drwxr-xr-x  11 root root  4400 Apr 23 23:12 dev
drwxr-xr-x  86 root root  4096 Apr 23 23:12 etc
drwxr-xr-x   3 root root  4096 Jan 21 06:20 home
drwxr-xr-x  14 root root  4096 Jan 21 02:30 lib
drwx------   2 root root 16384 Jan 21 06:11 lost+found
drwxr-xr-x   2 root root  4096 Jan 23 00:31 media
drwxr-xr-x   2 root root     0 Apr 23 23:12 misc
drwxr-xr-x   3 root root  4096 Jan 21 06:24 mnt
drwxr-xr-x   2 root root     0 Apr 23 23:12 net
-rw-r--r--   1 root root     0 Apr 24 00:16 newroot
drwxr-xr-x   2 root root  4096 Jan 20 22:24 opt
drwxr-xr-x   2 root root  4096 Jan 21 02:01 oracle_setup
dr-xr-xr-x 135 root root     0 Apr 24  2013 proc

。。。。。

注意,这个newroot文件可以事先不创建,当执行到重定向的命令后,若不存在此文件,系统会自动创建,如果这个文件事先存在,那么系统会先将这个文件清空,然后写入重定向的数据。那么如何才能不清空,而是在这个文件里累加重定向输出的内容呢?很简单,就是用 >> 重定向!!


正确输出与错误输出:

我们再来看另外一个问题,当年,我们用find命令去查找一个文件的时候,有时候因为普通用户的权限问题而导致了文件夹内的数据不可读取,而有些文件夹是这个用户有权限读取的,这样一来,就会出现两种结果,有找出来的对应文件,有出现无权限读取的错误。如果想要将正确的与错误的数据分别存入不同的档案中需要怎么做?在数据的重导向方面,正确的写法应该是『 1> 』与『 2> 』才对!但是如果只有 > 则预设是以 1> 来进行数据的!那个 1> 是输出正确数据, 2> 则是错误数据输出项目。

也就是说:
• 1> :是将正确的数据输出到指定的地方去
• 2> :是将错误的数据输出到指定的地方去

[liu@localhost /]$ find -name bin 1>/home/liu/list_right 2>/home/liu/list_error
[liu@localhost /]$ cd /home/liu
[liu@localhost ~]$ ls
bin  Desktop  list_error  list_right
[liu@localhost ~]$ more list_error 
find: ./var/spool/cron: Permission denied
find: ./var/spool/clientmqueue: Permission denied
find: ./var/spool/mqueue: Permission denied
find: ./var/spool/cups: Permission denied
find: ./var/spool/at: Permission denied
find: ./var/log/ppp: Permission denied
find: ./var/log/samba: Permission denied
find: ./var/log/audit: Permission denied
find: ./var/empty/sshd: Permission denied
find: ./var/lock/lvm: Permission denied
find: ./var/cache/samba/winbindd_privileged: Permission denied
find: ./var/gdm: Permission denied
find: ./var/lib/mlocate: Permission denied

。。。。。。

那么如果我们只想要正确的数据,错误的数据不要了呢?这个时候,/dev/null 这个文件就很重要了。那么这个/dev/null是什么呢?可以理解为有点像一个黑洞的垃圾桶功能,到你输入任何东西导向这个虚拟的垃圾桶的时候,它就会让这个数据消失了。。。。

另外, 如果我要将数据都写到同一个档案中呢?这个时候写法需要用到特殊写法,请注意底下的写法呦!
[dmtsai@linux ~]$ find /home -name testing > list 2> list <==错误写法
[dmtsai@linux ~]$ find /home -name testing > list 2>&1 <==正确写法

请特别留意这一点呢!同时写入同一个档案需要使用 2>&1 才对呦!

OK!了解了 >, 2>, >> 与 /dev/null 之后,那么那个 < 又是什么呀!?呵呵!以最简单的说法来说, 那就是『将原本需要由键盘输入的数据,经由档案来读入』的意思。 举例来说,我们可以使用 cat 在键盘上面输入一些数据,然后写入一个档案内,例如:
[root@linux ~]# cat > catfile
testing
cat file test
<==这里按下 [ctrl]+d 结束输入来离开!(我突然发现,这个cat命令也可以创建一个文件看来)
此时就会有 catfile 这个档案产生,而且该档案的内容就是刚刚输入的内容喔。 那么,我是否可以使用其它档案来取代键盘输入呢?可以啊!这样做!


[root@linux ~]# cat > catfile < somefile
我可以先编辑 somefile ,然后再以上述的指令来将数据输出到 catfile 去呢!

 能够理解 < 之后,再来则是怪可怕一把的 << 这个连续两个小于的符号了~ 他代表的是『结束的输入字符』的意思!举例来讲:『我要用 cat 直接将输入的讯息输出到 catfile 中, 且当输入 eof 时,该次输入就结束』,那我可以这样做:
[root@linux ~]# cat > catfile <<eof
> This is a test testing
> OK now stop
> eof <==输入这个玩意儿,嘿!立刻就结束了!

看到了吗?利用 << 右侧的控制字符,我们可以终止一次输入, 而不必输入 [crtl]+d 来结束哩!


2、命令执行的判断依据     ;   &&     ||

;表示执行完前一个命令,继续执行后一个命令例如关机时,希望我可以先执行两次 sync ,然后才 shutdown 计算机,那么可以怎么作呢?这样做呀:
[root@linux ~]# sync; sync; shutdown -h now

&& 表示前面一个指令执行未出现错误,则执行后一个指令。若前一个出错,则不再执行后面指令。

||  表示前面一个指令若执行错误,则执行后面指令,若前一个指令没有出错,则后面指令不再执行(正好与&&相反)。

例题:以 ls 测试 /tmp/vbirding 是否存在,若存在则显示 "exist" ,若不存在,则显示 "not exist"!

答:
这又牵涉到逻辑判断的问题,如果存在就显示某个数据,若不存在就显示其它数据,那我可以这样做:

ls /tmp/vbirding && echo "exist" || echo "not exist"

意思是说,当 ls /tmp/vbirding 执行后,若正确,就执行 echo "exist" ,若有问题,就执行 echo "not exist" !那如果我写成:
ls /tmp/vbirding || echo "not exist" && echo "exist"
对不对啊?这其实是有问题的,为什么呢?因为指令是一个一个往下执行,因此,在上面的例子当中,如果 /tmp/vbirding 不存在时,他会:
1. 若 ls /tmp/vbirding 不存在,因此回传一个非为 0 的数值;
2. 接下来经过 || 的判断,发现前一个指令回传非为 0 的数值,因此,程序开始执行 echo "not exist" ,而 echo "not exist" 程序肯定可以执行成功,因此会回传一个 0 值给后面的指令;
3. 经过 && 的判断,咦!是 0 啊!所以就开始执行 echo "exist" 。

所以,第二个例子里面竟然会同时出现 not exist 与 exist 呢!


3、双向重定向(三通)


我们可以利用tee命令将数据流分送到文件与屏幕,对于linux系统来书,其stdout就是指的屏幕。

[root@linux ~]# tee [-a] file
参数:
-a :以累加 (append) 的方式,将数据加入 file 当中!


范例:
[root@linux ~]# last | tee last.list | cut -d " " -f1

# 这个范例可以让我们将 last 的输出存一份到 last.list 档案中;

这里区分一下这两个命令:

[root@localhost log]# last |cut -c 2-15|tee last2

[root@localhost log]# last |tee last2 |cut -c 2-15

一眼看上去,顺序变了,对结果造成什么影响呢?按照对管道符号“|” 的理解,我们可以知道,第一个会先用cut命令截取了数据然后显示到屏幕,在将已经截取好的数据存入last2文件内。

而第二个,会将last命令的所有内容先存的last2(不执行截取),然后对显示到屏幕上的内容执行cut命令截取数据。


[root@linux ~]# ls -l /home | tee ~/homefile | more
# 这个范例则是将 ls 的数据存一份到 ~/homefile ,同时屏幕也有输出讯息!


[root@linux ~]# ls -l / | tee -a ~/homefile | more
# 要注意: tee 后接的档案会被覆盖,所以,我们要加上 -a 这个参数才能将讯息累加。
有没有发现在命令重导向的时候,如果我们要将数据送出到档案的时候, 屏幕上就不会出现任何的数据!那么如果我们需要将数据同时显示在屏幕上跟档案中呢?呵呵!这个时候就需要 tee 这个指令啰!使用 last 可以查看到这个月份的登入资料,而使用了 tee 之后,会将数据同时传给下一个命令去执行,也会将数据写入 last.list 这个档案中!


相关文章
|
30天前
|
Linux Shell
【Linux 进程间通讯 管道】使用Linux管道进行linux进程间通信
【Linux 进程间通讯 管道】使用Linux管道进行linux进程间通信
31 1
|
Unix Linux Windows
【Linux】—— 命名管道详解
【Linux】—— 命名管道详解
|
3月前
|
Unix Linux C语言
Linux重定向:深入理解与实践
Linux重定向:深入理解与实践
|
3月前
|
Linux
Linux dup函数文件重定向
dup函数创建一个新的文件描述符,该新文件描述符和原有文件描述符file_descriptor指向相同的文件、管道或者网络连接。并且dup返回的文件描述符总是取系统当前可用的最小整数值。dup2和dup类似,不过它将返回第一个不小于file_descriptor_two的整数值。dup和dup2系统调用失败时返回-1并设置errno。有时我们希望把标准输入重定向到一个文件,或者把标准输出重定向到一个网络连接(比如CGI编程)。
19 0
|
1月前
|
缓存 Unix Linux
进程间通信之匿名管道和命名管道的理解和实现【Linux】
进程间通信之匿名管道和命名管道的理解和实现【Linux】
|
1月前
|
消息中间件 Unix Linux
【Linux】—— 匿名管道
【Linux】—— 匿名管道
|
存储 Shell Linux
Linux--文件(2)-重定向和文件缓冲
Linux--文件(2)-重定向和文件缓冲
|
2月前
|
Linux C++
认识Linux指令之 “ 重定向” 符号
认识Linux指令之 “ 重定向” 符号
认识Linux指令之 “ 重定向” 符号
|
2月前
|
Linux C语言
Linux:重定向
Linux:重定向
73 1
|
2月前
|
Unix Shell Linux
在Unix/Linux Shell中,管道(`|`)和重定向
在Unix/Linux Shell中,管道(`|`)和重定向
23 1