1 说在前面
- 基于Centos 6.9
- 有经验的可以直接跳到最后总结
- 重定向中的一个细节,暂未搞清楚
- 如果大家有兴趣(评论下),我可以把高阶的再整理出来
2 重定向
2.1 文件描述符
首先来看三个文件
[root@testing ~]# ll /dev/std*
lrwxrwxrwx. 1 root root 15 Jun 7 2019 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx. 1 root root 15 Jun 7 2019 /dev/stdout -> /proc/self/fd/1
lrwxrwxrwx. 1 root root 15 Jun 7 2019 /dev/stderr -> /proc/self/fd/2
这3个就是系统的文件描述符:
1. stdin 标准输入 文件描述符fd=0
2. stdout 标准输出 文件描述符fd=1 [注:可以认为是标准正确输出]
3. stderr 标准错误 文件描述符fd=2
那什么是重定向呢?涉及到几个符号,初阶的就是:
1. > 输出重定向
2. >> 输出追加重定向
3. < 输入重定向
4. & 文件描述符
怎么来操作重定向呢?看鸟哥的解释吧:
那我们来看一些实例 ##2.2 重定向标准输出
[root@testing ~]# cat /etc/redhat-release
#正常看一个文件
CentOS release 6.9 (Final)
#输出到屏幕上(标准输出,且是正确的结果)
[root@testing ~]# ll /home/version
ls: cannot access /home/version: No such file or directory
#先确认一个文件不存在,后续之用
[root@testing ~]# cat /etc/redhat-release >/home/version
#执行命令后加>,再接一个文件,此时屏幕上就没有输出信息了,输出到哪里去了?
[root@testing ~]# cat /home/version
CentOS release 6.9 (Final)
#输出信息跑到这个文件里来了
[root@testing ~]# cat /etc/redhat-release 1>/home/version
#>和1>是一样的,1是默认值,命令后跟的空格1,这个数字就是文件描述符
[root@testing ~]# cat /home/version
CentOS release 6.9 (Final)
#1>和>的效果一样
[root@testing ~]# uname -a >/home/version
#如果再执行一个其他命令,输出到刚才的同一个文件中呢
[root@testing ~]# cat /home/version
Linux testing 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:29:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
#发现上一次的内容被覆盖了,只保留了最新的内容
这里能发现几个特征,在重定向>的时候
-
重定向>,等价于1>,1是默认值,标准输出
-
重定向的时候文件可以不存在,不存在就新建,存在就先清空再输出到文件 基于此,一个小技巧,清空文件最快的方法
[root@testing ~]# cat /home/version CentOS release 6.9 (Final) [root@testing ~]# >/home/version #重定向到一个文件,但什么都不做,那就是清空文件 [root@testing ~]# cat /home/version [root@testing ~]# #文件被清空了
##2.3 重定向标准错误 系统中的错误就很多了,包括但远远不限于
- 文件、目录不存在
- 命令不存在
- 权限不足
- 依赖缺失 ...
这样我们可以来重定向标准错误,跟标准输入一样一样的
[root@testing ~]# su - china
[china@testing ~]$ lk
-bash: lk: command not found
#china用户没有lk这个命令,这是错误信息!
[china@testing ~]$ lk 2>./error.info
#刚才的错误重定向到error.info这个文件中
[china@testing ~]$ cat error.info
-bash: lk: command not found
#验证了我们的想法,下面是另外一个例子,不赘述
[china@testing ~]$ ls -l /root/
ls: cannot open directory /root/: Permission denied
[china@testing ~]$ ls -l /root/ 2>./error.info2
[china@testing ~]$ cat error.info2
ls: cannot open directory /root/: Permission denied
[china@testing ~]$
##2.4 重定向追加 追加的意思就是append,尾部插入,保留原文件的内容,在尾部追加,如果文件不存在,也是创建新文件(但没有清空这一步)
[root@testing ~]# uname -a>/home/system.info
[root@testing ~]# cat /home/system.info
Linux testing 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:29:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
[root@testing ~]# uptime >>/home/system.info
#标准正确输出重定向追加
[root@testing ~]# uptime >>/home/system.info1
#系统不存在该文件
[root@testing ~]# cat /home/system.info
Linux testing 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:29:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
08:34:50 up 1:16, 4 users, load average: 0.00, 0.00, 0.00
[root@testing ~]# cat /home/system.info1
08:34:52 up 1:16, 4 users, load average: 0.00, 0.00, 0.00
标准错误同理,不再赘述
##2.5 标准错误和标准正确都重定向到某个文件中 系统中有些命令同时会有错误和正确的输出,特别是脚本是多条命令的组合,那非常有可能有正确和错误2部分。
- 以普通用户执行find / -name profile,
- 一个脚本有正确和错误的命令:
常规的思路是 command >file 2>>file,或者command 2>file 1>>file 但这其实是有问题的也是让我费解的地方。
[root@testing ~]# cat test.sh
#写一个简单的脚本,包含一条正确的命令和一条错误的命令
uname
lk
[root@testing ~]# ./test.sh
Linux
./test.sh: line 2: lk: command not found
[root@testing ~]# ./test.sh >file1 2>file2
#正确输出到file1,错误输出到file2
[root@testing ~]# cat file1
Linux
[root@testing ~]# cat file2
./test.sh: line 2: lk: command not found
#没毛病
[root@testing ~]# ./test.sh >file1 2>>file1
[root@testing ~]# cat file1
Linux
./test.sh: line 2: lk: command not found
#没毛病+1
下面来毛病了,就是我不懂的地方了!
[root@testing ~]# cat test.sh
uname
lk
uname
#脚本里面的命令是正确-错误-正确
[root@testing ~]# ./test.sh >file1 2>>file1
#正确输出到file1,错误追加到file1
[root@testing ~]# cat file1
Linux
Linux
.sh: line 2: lk: command not found
#注意:文件内容是正确在一块,错误在一块
[root@testing ~]# ./test.sh 2>file1 >>file1
#**可如果这么写呢?**
[root@testing ~]# cat file1
./test.sh: line 2: lk: command not found
Linux
#丢了一个正确的!我也不知道为何。
标准输出和标准错误都要定向到一个文件,正确的姿势应该是这样的,不建议用分别输出、结合追加的方式 [root@testing ~]# ./test.sh >file 2>&1 [root@testing ~]# cat file Linux ./test.sh: line 2: lk: command not found Linux
画了个草图
给出示例:
[root@testing ~]# ./test.sh >file 2>&1
#方法1
[root@testing ~]# cat file
Linux
./test.sh: line 2: lk: command not found
Linux
[root@testing ~]# ./test.sh 2>file1 1>&2
#方法2
[root@testing ~]# cat file1
Linux
./test.sh: line 2: lk: command not found
Linux
[root@testing ~]# ./test.sh &>file2
#方法3
[root@testing ~]# cat file2
Linux
./test.sh: line 2: lk: command not found
Linux
3 总结
- 标准输出重定向 command >file
- 标准输出追加重定向 command >>file
- 标准错误重定向 command 2>file
- 标准错误追加重定向 command 2>>file
- 标准输出和标准错误重定向到1个文件
- command >file 2>&1
- command 2>file 1>&2
- command &>file
这只是初阶的,囧