The Linux Command Line-WILLIAM(1)-文件IO

321 阅读4分钟

1 关于Linux中I/O

迄今为止所用到的程序的输出结果,一般包含两种类型

  • 程序执行后的结果

  • 错误信息

例如ls命令,可以在屏幕上看到执行结果以及错误信息。 在Linux中一切即文件,ls命令实际上将他的执行结果发送到了一个特殊的标准输出文件standard output (stdout),并且把他的执行的错误信息发送到了另一个文件standard error (stderr),默认情况下,这两个文件连接到屏幕并且并不保存在磁盘中。

另外,许多程序从标准输入文件standard input(stdin)中取得输入,stdin文件默认情况下与键盘连接。

2 关于I/O重定向

2.1 关于输出重定向

2.1.1 标准输出(standard output)重定向

I/O重定向允许改变在哪里输入输出,默认情况下在屏幕上输出,从键盘输入,可以用I/O重定向来改变输入输出流。重定向的命令格式为:用>符号后面加上文件名称来重定向输出到文件中。例如:

[me@linuxbox ~]ls -l /usr/bin > ls-output.txt

但是当/usr/bin文件夹换成不存在的文件夹时候将会出现错误信息:

[me@linuxbox ~]$ ls -l /bin/usr > ls-output.txt
ls: cannot access /bin/usr: No such file or directory

为什么加了重定向到文件后错误信息依然打印在屏幕上呢?这是因为ls命令并不将他的错误信息发送给标准输出文件standard output (stdout)文件而是发送到了standard error (stderr),由于只重定向了stdout,因此错误信息依旧显示在屏幕上。

当执行完上述两个命令后接着执行

[me@linuxbox ~]$ ls -l ls-output.txt
-rw-rw-r-- 1 me   me   0 2012-02-01 15:08 ls-output.txt

可以看到文件大小变成了0,这是因为每一次重定向都会重写文件中内容。因为上述第二个命令选择了错误的目录而导致结果为空因此这个结果覆盖了原来文件中写入的第一个命令执行后的结果。由于这个特性,如果想要清空文件或是创建新的空文件可以使用以下命令:

[me@linuxbox ~]$> ls-output.txt

不想要每次的结果都覆盖上次的内容,这时候可以使用 >> 操作符来重定向输出到文件,这样输出结果不会重写文件而是追加到文件内容。

2.1.2 标准错误(standard error)重定向

要重定向标准错误,我们必须参考它的文件描述符。一个程序可以处理多个输入输出流,前三个文件流分别为-输入,输出以及错误,shell在内部引用他们作为文件描述符分别为0,1,2。shell为使用文件描述符号来重定向输出流文件提供了一种文件描述数字表示方法。因为stand error与文件描述符号2相同因此可以用以下命令:

[me@linuxbox ~]$ ls -l /bin/usr 2> ls-error.txt

上述命令代表着标准错误的文件描述符2必须紧挨着文件重定向符号>

想要重定向命令执行结果以及错误信息到文件,有两种方式:

  • 传统方法,在shell早期版本:
[me@linuxbox ~]$ ls -l /bin/usr > ls-output.txt 2>&1

此种方法首先重定向了standard output 输出流到ls-output.txt文件,紧接着声明2>&1重定向了文件描述符号2(standard error)到文件描述符1(standard output)。

注:重定向顺序必须先重定向输出到文件接着在把error重定向到输出流,否则error依旧会输出在屏幕上。

  • 新版本提供了新的简化的方法:
[me@linuxbox ~]$ ls -l /bin/usr &> ls-output.txt

此方法用了&> 来重定向standard output 以及 standard error 到文件中

处理不期望的输出:

Linux系统提供了一种方式来重定向输出到一个指定文件/dev/null。这个文件为系统设备叫做bit bucket,它允许输入并且不做任何操作。

ls -l /bin/usr 2> /dev/null

2.1.3 标准输入(standard input)重定向

2.1.3.1 关于cat命令

  • cat命令可以显示文件内容
  • 可以用cat命令把分散的文件合并成原来完整的文件
  • 无参数情况下cat从standard input粘贴内容到standard output
  • 创建短文本文件

下面是一些示例, 显示文件内容:

[me@linuxbox ~]$ cat ls-output.txt

当下载一个大文件分成多个部分下载过来的时候,命名类似于 movie.mpeg.001 movie.mpeg.002 ... movie.mpeg.099 可以用以下命令合并成一个文件。

[me@linuxbox ~]$ cat movie.mpeg.0* > movie.mpeg

因为通配符匹配时候按照顺序,参数将会以正确的方式排列,因此将会得到正确的结果。

执行[me@linuxbox ~]$ cat命令,按下回车后将会发现命令行挂在那里等待用户输入,因为标准输入(standard input)默认从键盘读取输入,因此当在键盘上输入的时候,可以看到屏幕上也回显输入的内容,当用户按下回车后,cat命令把标准输入(standard input)粘贴内容到标准输入(standard output)因此在新的一行将会看到输出的键入内容。输入完毕后输入CTRL-D组合键来告诉cat 它到了输入的end-of-file(EOF)符号退出命令。

[root@izuf67yuy6secatlp4sztez ~]# cat
dfdf
dfdf

无参数情况下cat从标准输入(standard input)粘贴内容到标准输入(standard output),可以利用这一特性来创建短文本文件:

[me@linuxbox ~]$ cat > lazy_dog.txt
The quick brown fox jumped over the lazy dog.

这时输入将会重定向到文件中。

2.1.3.2 输入重定向

可以用重定向符号<来表示输入的重定向。例如,将标准输入(standard input)从默认键盘输入改为文件输入:

[me@linuxbox ~]$ cat < lazy_dog.txt
The quick brown fox jumped over the lazy dog

3 关于管道(Pipelines)

3.1 管道(Pipelines)

命令从标准输入(standard input)读取,处理之后发送到标准输出(standard output)。 使用管道操作符(pipe operator )|,一个命令的标准输出(standard output)可以作为另一个命令的标准输入(standard input),命令的格式为:

command1 | command2

可以使用less命令可以方便的检查生产标准输出的任何命令的输出:

[me@linuxbox ~]$ ls -l /usr/bin | less

3.2 过滤器(Filters)

可以将多个命令放入管道,这些命令通常称为过滤器(Filters)。过滤器取得输入,将其处理后输出。

一些例子:

排序:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | less

上面ls命令 因为指定了两个文件夹,因此首先输出两个顺序表,通过加入sort命令到管道中,改变原来的两个顺序表合并输出为一个有序列表。

在排序列表基础上去除具有重复名称的文件:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq | less

在排序列表基础上去除不重复名称的文件:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq -d| less

wc命令可以打印出文件的行,单词,字节的统计信息,例如:

[me@linuxbox ~]$ wc ls-output.txt 
7902  64566 503634 ls-output.txt

因此可以使用wc命令作为过滤器。在排序列表基础上wc 打印统计信息,-l指定行数:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq | wc -l

grep 命令可以打印匹配模式(Pattern)的字符串,并且在后面可以用正则表达式来作为参数:

[me@linuxbox ~]$ ls /bin /usr/bin | sort | uniq | grep zip

打印包含zip字符串的文件名;后面可以使用常用选项-i忽视大小写,-v打印不与模式匹配的文件名。

head/ tail 命令可以查看开始/结尾 10行的信息,可以用-n + number 来修改查看行数:

[me@linuxbox ~]$ ls /usr/bin | tail -n 5

tee 命令可以从标准输入读并输出到标准输出和文件中:

[me@linuxbox ~]$ ls /usr/bin | tee ls.txt | grep zip

在grep筛选之前将整个文件夹内容结果存入了ls.txt文件中。