本节讨论一下几个问题:
1. 文件描述符。
2. 重定向。
3. 管道符
4. tee的用法。
1. 文件描述符。
在linux系统中一切皆文件。文件夹和设备都是文件。如何用来区别不同的文件呢?这里的区别不是我们在windows下看到的后缀名不同来区别。也不是我们在linux下用ls 命令看到的不同文件的列表。这里的文件描述符主要讨论的是对文件操作的一个标识符。无操作就无标识符。 比如两个进程同时在对同一个文件进行读操作。
如何区分这两个读操作呢?这就需要文件文件描述符来区别了。每一次打开一个文件就形成了一个文件描述符,后打开的描述符一般都要比先打开的文件描述符大。
比如:我们可以man 一下 open函数。 看一下返回值:
[root@xiaolyu ~]# man open
也就是说文件描述符是一个整数。当然了,系统默认最大是1024. 我们不妨用ulimit -n 来查看一下。
我们也可以查看一下:man socket 一下 看一下效果:
也就是说文件描述符可以通过多种途径来生成。记住:只要对文件进行操作,就会返回文件描述符。
然后我们来看看系统自带的3个文件描述符。
这三个是最小的文件描述符,我们自己操作文件,返回的文件描述符最小都是从4开始的。
stdin 标准输入 默认的设备是键盘 文件描述符为:0
命令将从标准输入文件中 读取 在执行过程中的 需要的 输入数据. -->数据来源于文件
stdout 标准输出 默认的设备是 显示器 文件描述符为:1
命令执行后的输出结果,发送到标准输出文件. -->结果输出到文件
stderr 标准错误 默认的设备是显示器 文件描述符为:2
命令将执行期间的各种错误信息发送到标准错误文件 -->错误信息发送到文件
标准输入,标准输出和标准错误默认使用键盘和显示器作为关联设备与操作系统进行交互完成最基本的输入,输出操作.
我们不妨用man stdin 来看一下:[root@xiaolyu ~]# man stdin
以上便是关于文件描述符。
2. 重定向.
重定向包含:重定向输出和重定向输入:
重定向输出:
将命令的正常输出结果保存到指定的文件中,而不是直接显示在显示器的屏幕上
重定向输出使用”>” “>>” 操作符号
> 覆盖文件
>> 追加内容
若重定向的输出的文件不存在,则会新建该文件
eg: 查看当前主机的CPU的类型保存到kernel.txt文件中(而不是直接显示到屏幕上)
uname -p 查看cpu类型信息
将内核 的版本信息 和操作系统信息 追加到kernel.txt
重定向输出就将结果输出到文件中(覆盖和追加两种方式)
重定向输入
将命令中接收输入的途径由默认的键盘改为其他文件.而不是等待从键盘输入
从文件读取数据
操作符: “<”
通过重定向输入可以使一些交互式操作过程能够通过读取文件来完成
eg:使用passwd 设置密码时.每次都根据提示输入密码比较烦琐
改用重定向输入将可以忽略交互式的过程.而自动完成密码设置 (结合—stdin 选项来识别标准的输入)
使用非交互式的去执行设置密码:
[root@xiaolyu ~]# touch passwd.txt
[root@xiaolyu ~]# vim passwd.txt
[root@xiaolyu ~]# useradd zhangsan
useradd: user 'zhangsan' already exists
[root@xiaolyu ~]# useradd lisi
[root@xiaolyu ~]# passwd --stdin lisi < passwd.txt
Changing password for user lisi.
passwd: all authentication tokens updated successfully.
重定向输入就是通过文件中的内容作为输入的数据
错误重定向:
将命令执行过程中出现的错误信息 (选项或参数错误) 保存到指定的文件,而不是直接显示到显示器
错误信息保存到文件
操作符: 使用2>
2指的是错误文件的编号 (在使用标准的输入和输出省略了1 0 编号)
在实际应用中,错误重定向可以用来收集执行的错误信息.为排错提供依据;
对于shell脚本还可以将无关紧要的错误信息重定向到空文件/dev/null中 以保持脚本输出的简洁
eg: 使用tar命令进行备份的时候出新的错误信息保存到err.log文件中
把/dev/null看作"黑洞". 它非常等价于一个只写文件. 所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到. 然而, /dev/null对命令行和脚本都非常的有用.
echo $? 表示最近一次操作是否成功 。 0 成功 非零不成功
正确的写到一个文件,错误的在写到一个文件
[root@xiaolyu ~]# ls /tmp/ /nginx 1> a.txt 2>b.txt
保存到一张图片比较清爽:
输出到同一个文件中:
[root@xiaolyu ~]# ls /tmp/ /nginx/ 1>a.txt 2>&1
或者以下这种写法 ,重定向到文件的1可以省略,因为默认就是1.
[root@xiaolyu ~]# ls /tmp/ /nginx/ >a.txt 2>&1
&> 混合输出
不分正确的还是错误的
[root@xiaolyu ~]# ls /opt/ /mysql &> a.txt
3. 管道符
这里只提管道符,关于管道有专门创建管道的函数,以及有名管道和无名管道,以及管道之间的通信,我放在IPC通信中阐述。
管道符,可以把两条命令连起来,前面一条命令的输出当成后面一条命令的输入。
eg: 查看nginx的进程。
[root@xiaolyu ~]# ps -aux | grep nginx
eg: 查看某个进程的端口:
4. tree命令。
功能:读取标准输入的数据,并将其内容输出成文件。
语法:tee [-a][--help][--version][文件...]
tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
参 数:
-a或 --append 追加
--help 在线帮助。
--version 显示版本信息
eg1
[root@xiaolyu ~]# who 查看用户登录信息
root :0 2016-08-13 07:58 (:0)
root pts/0 2016-08-13 11:21 (:0)
[root@xiaolyu ~]# who | tee who.out
将who的结果输出到who.out文件 ,同时在终端显示:
eg2
[root@xiaolyu ~]# pwd
| tee -a who.out 追加
要注意的是:在使用管道线时,前一个命令的标准错误输出不会被tee读取。
[root@xiaolyu ~]# ls -l yyy | tee -a who.out