Linux重定向

重定向能够实现Linux命令的输入输出与文件之间重定向,以及实现将多个命令组合起来实现更加强大的命令。这部分涉及到的比较多的命令主要有:

  • cat:连接文件
  • sort:排序文本行
  • uniq:忽略或者报告重复行
  • wc:统计文件的行数、词数、字节数
  • grep:打印匹配制定模式的行
  • head:输出文件的头部
  • tail:输出文件的尾部
  • tee:从标准输入读,并往标准输出或者文件写

1.重定向标准输出

使用>可以将本来出现在屏幕的标准输出信息重定向到一个文件中。我们需要将某个目录下所有文件及目录的列表保存在一个文本文件中:

jerry@ubuntu:~$ ls -l /usr/ > ls.txt
jerry@ubuntu:~$ cat ls.txt 
total 64
drwxr-xr-x   2 root root 20480 2012-12-08 17:33 bin
drwxr-xr-x   2 root root  4096 2012-02-03 17:21 games
drwxr-xr-x  37 root root  4096 2012-12-08 17:33 include
drwxr-xr-x  58 root root 20480 2012-12-08 17:33 lib
lrwxrwxrwx   1 root root     3 2012-12-08 01:29 lib64 -> lib
drwxr-xr-x  11 root root  4096 2012-12-08 02:38 local
drwxr-xr-x   2 root root  4096 2012-12-08 02:25 sbin
drwxr-xr-x 106 root root  4096 2012-12-08 02:18 share
drwxrwsr-x   4 root src   4096 2012-12-08 01:33 src

现在我们ls一个不存在的目录,并且重定向到文本文件中:

jerry@ubuntu:~$ ls -l /usr/notexist > ls.txt
ls: cannot access /usr/notexist: No such file or directory

这时我们看到错误信息。再看看文件ls.txt,我们会发现:

jerry@ubuntu:~$ ls -l ls.txt 
-rw-r--r-- 1 jerry jerry 0 2012-12-15 22:22 ls.txt

我们可以看到,这个文件中没有任何内容。一方面,ls以及很多Linux命令的错误信息会打印到标准输出文件中,而这里的内容是不会被>操作符重定向到文件中的。另一方面,我们看到,之前在ls.txt文件中的内容也没了,也就是说>操作符是会覆盖原有内容的。

使用>>可以在实现重定向时不覆盖原有内容,而是在文件末尾追加内容。我们可以看一下例子:

jerry@ubuntu:~$ ls -l /usr/ >> ls.txt
jerry@ubuntu:~$ ls -l /usr/ >> ls.txt
jerry@ubuntu:~$ cat ls.txt 
total 64
drwxr-xr-x   2 root root 20480 2012-12-08 17:33 bin
drwxr-xr-x   2 root root  4096 2012-02-03 17:21 games
drwxr-xr-x  37 root root  4096 2012-12-08 17:33 include
drwxr-xr-x  58 root root 20480 2012-12-08 17:33 lib
lrwxrwxrwx   1 root root     3 2012-12-08 01:29 lib64 -> lib
drwxr-xr-x  11 root root  4096 2012-12-08 02:38 local
drwxr-xr-x   2 root root  4096 2012-12-08 02:25 sbin
drwxr-xr-x 106 root root  4096 2012-12-08 02:18 share
drwxrwsr-x   4 root src   4096 2012-12-08 01:33 src
total 64
drwxr-xr-x   2 root root 20480 2012-12-08 17:33 bin
drwxr-xr-x   2 root root  4096 2012-02-03 17:21 games
drwxr-xr-x  37 root root  4096 2012-12-08 17:33 include
drwxr-xr-x  58 root root 20480 2012-12-08 17:33 lib
lrwxrwxrwx   1 root root     3 2012-12-08 01:29 lib64 -> lib
drwxr-xr-x  11 root root  4096 2012-12-08 02:38 local
drwxr-xr-x   2 root root  4096 2012-12-08 02:25 sbin
drwxr-xr-x 106 root root  4096 2012-12-08 02:18 share
drwxrwsr-x   4 root src   4096 2012-12-08 01:33 src

2.重定向标准错误信息到文件

没有单纯的一个操作符可以将标准错误信息重定向到文件中。要实现这一点有两种办法。第一种使用文件描述符,在shell中,默认用数字0,1,2分别代表标准输入、标准输出、标准错误。要将标准错误信息重定向到文件中,可以如下操作:

jerry@ubuntu:~$ ls /usr/notexist 2>lserr.txt
jerry@ubuntu:~$ cat lserr.txt 
ls: cannot access /usr/notexist: No such file or directory

如果要同时将标准输出和标准错误信息同时输出到文件中,则需要如下操作:

jerry@ubuntu:~$ ls -l /usr/notexist > lsboth.txt 2>&1
jerry@ubuntu:~$ cat lsboth.txt 
ls: cannot access /usr/notexist: No such file or directory

在比较新的shell中,还可以有另一种办法如下:

jerry@ubuntu:~$ ls -l /usr/notexist &> lsboth.txt
jerry@ubuntu:~$ cat lsboth.txt 
ls: cannot access /usr/notexist: No such file or directory

3.屏蔽不想看到的信息

Linux中有一个特殊的文件/dev/null,这个文件叫做bit bucket,可以接受输入信息但是什么都不做。因此要抑制命令的输出信息,只需要如下操作:

ls /usr/ > /dev/null

4.重定向标准输入

cat命令可以接受一组文件为参数,将这些文件复制到标准输出。我们前面的例子中已经多次使用到cat命令来将文本文件的内容读取到屏幕上。cat还有一个很重要的功能:接受一组文件,然后通过重定向将他们重新组合到一个文件中。我们看一个例子:

jerry@ubuntu:~$ cat ls1
aaaaaaaaaaaaaaaaaaaaaaaa
jerry@ubuntu:~$ cat ls2
bbbbbbbbbbbbbbbbbbbbbbbb
jerry@ubuntu:~$ cat ls1 ls2 > ls
jerry@ubuntu:~$ cat ls
aaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbb

cat ls1 ls2 > ls这个命令将ls1和ls2文件中的内容合并到ls文件中了。cat命令的这种功能不仅仅适用于文本文件,同样对二进制文件有效。这个场景主要在将多个压缩包文件合并到一个压缩包中用到。

cat也可以不传递参数,这种情况下,cat会重定向标准输入到标准输出。我们看一个例子:

jerry@ubuntu:~$ cat
aaaaaaaaaaa
aaaaaaaaaaa
bbbbbbbbbbbbbb             
bbbbbbbbbbbbbb

在这个例子中,键入一行文本,按下回车键之后,刚才输入的内容会立刻显示到屏幕,因此我们看到每两行文本都是一样的。当然我们可以使用<来表示输入重定向。我们要想将文件内容重定向到输出,可以使用cat < file,只是这种方式不如直接cat file来得直接。

5.管道

Linux提供|操作符,该操作符可以将一个命令的输出作为另一个命令的输入,这样通过多个命令的协作来完成一些比较复杂的内容。比如,我们可以通过uniq命令来排除重复的行。但是uniq命令往往需要和sort命令配合使用。因为uniq接收一组排好序的文本,而刚好sort可以将文本行排序。我们看下面的例子:

jerry@ubuntu:~$ cat ls
aaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaaaaaaaaaa
jerry@ubuntu:~$ cat ls | sort | uniq
aaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbb

我们还可以对uniq命令加上-d选项来查看重复的行,如下:

jerry@ubuntu:~$ cat ls | sort | uniq -d
aaaaaaaaaaaaaaaaaaaaaaaa

使用wc命令可以统计文本的行数、单词书和字节数。可以和例如ls命令的输出一起组成管道命令:

jerry@ubuntu:~$ ls /bin /usr/bin/ | sort | uniq | wc
    764     763    6347

如果仅仅想要统计行数,只需要在wc命令后面添加-l选项即可。wc命令常用来统计代码的行数。

find cn/ -name "*.php" |xargs cat|wc -l

上面这个例子统计了cn目录下所有php文件的行数之和。

grep命令用来查找匹配的模式,并且打印包含该模式的行。举个例子:

jerry@ubuntu:~$ ls /bin /usr/bin/ | sort | uniq | grep zip
bunzip2
bzip2
bzip2recover
funzip
gpg-zip
gunzip
gzip
unzip
unzipsfx
zipgrep
zipinfo

在这个例子中,zip就是一个模式,表示包含字符串zip。我们在/bin和/usr/bin目录下找出名字带有zip的程序,并且打印这些程序的名字。grep命令可以使用正则表达式,功能也非常强大,这里我们不侧重介绍。

head和tail命令也常常用于组成管道命令。head可以查看文件或者文本的前面部分。tail查看文件或者文本的末尾部分。二者都可以接收-n选项,表示显示的行数。看例子:

jerry@ubuntu:~$ ls /bin/ | head -n 5
bash
bunzip2
busybox
bzcat
bzcmp
jerry@ubuntu:~$ ls /bin/ | tail -n 5
zforce
zgrep
zless
zmore
znew

tail还有一个重要的用处,就是实时显示某些程序的日志文件。tail能接受一个选项-f,实时显示出新添加到文件末尾的行数。这样一旦有新的行追加到日志文件的末尾,就会被实时显示在后面。

jerry@ubuntu:~$ tail -f /var/log/messages
Dec 16 06:40:20 ubuntu rsyslogd: [origin software="rsyslogd" swVersion="4.2.0" x-pid="533" x-info="http://www.rsyslog.com"] rsyslogd was HUPed, type 'lightweight'.

最后再介绍一个tee命令,它可以接收标准输入的内容并且同时将内容重定向到标准输出以及一个或者多个文件中,直接看例子:

jerry@ubuntu:~$ ls /bin/ | tee tee.txt | grep zip
bunzip2
bzip2
bzip2recover
gunzip
gzip
jerry@ubuntu:~$ cat tee.txt 
bash
bunzip2
busybox
bzcat
bzcmp
bzdiff
bzegrep
bzexe
bzfgrep
bzgrep
bzip2
bzip2recover
bzless
bzmore
cat
checkpassword
chgrp
chmod
chown
chvt
cp
cpio
dash
date
dd
df
dir
dmesg
dnsdomainname
domainname
dumpkeys
echo
ed
egrep
false
fgconsole
fgetty-login
fgetty-login2
fgrep
fuser
fusermount
grep
gunzip
gzexe
gzip
hostname
ip
kbd_mode
kill
less
lessecho
lessfile
lesskey
lesspipe
ln
loadkeys
login
ls
lsmod
mkdir
mknod
mktemp
more
mount
mountpoint
mt
mt-gnu
mv
nano
nc
nc.openbsd
netcat
netstat
nisdomainname
ntfs-3g
ntfs-3g.probe
ntfs-3g.secaudit
ntfs-3g.usermap
open
openvt
pidof
ping
ping6
plymouth
ps
pwd
rbash
readlink
rm
rmdir
rnano
run-parts
sed
setfont
setupcon
sh
sh.distrib
sleep
static-sh
stty
su
sync
tailf
tar
tempfile
touch
true
ulockmgr_server
umount
uname
uncompress
unicode_start
vdir
which
ypdomainname
zcat
zcmp
zdiff
zegrep
zfgrep
zforce
zgrep
zless
zmore
znew

 

 

参考书:

《The Linux Command Line》    William E. Shotts, JR.    no starch press

 

posted @ 2012-12-16 12:43  wawlian  阅读(13110)  评论(2编辑  收藏