Linux重定向
重定向概述:
什么是重定向:
Linux中的重定向就是将原本要输出到屏幕中的数据信息,重新指向某个特定文件当中,或者定向到黑洞文件(/dev/null)中。
重定向的作用:
- 当屏幕输出的信息很重要,希望保存时
- 后台执行的程序一般都会有输出,不希望它输出干扰到终端
- 执行定时备份任务,希望将备份结果保留下来时
- 执行一些命令,会提示一些报错信息,可以直接将报错丢弃。
- 执行命令时希望将报错和正确内容区分在不同文件中时(日志)
命令返回值(拓展)
在Linux下,不管是启动桌面程序还是执行命令,所有程序在结束时都会返回一个数字值,这个值叫做返回值,或者称为错误号。
[root@localhost ~]# ls
[root@localhost ~]# echo $?
0
我们执行ls命令,通过echo$?,打印$?的值,我们发现返回值是0
返回值是0,则代表上一条命令执行成功返回值
非0,则代表上一条命令执行不成功
文件描述符
li可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作。 用户可以自定义文件描述符范围是:3-num,这个最大数字,跟用户的:ulimit –n 定义数字有关系,不能超过最大值。
linux启动后,会默认打开3个文件描述符,分别是:标准输入standard input 0,正确输出standard output 1,错误输出:error output 2。以后打开文件后。新增文件绑定描述符可以依次增加。 一条shell命令执行,都会继承父进程的文件描述符。因此,所有运行的shell命令,都会有默认3个文件描述符。
名称 | 文件描述符 | 作用 |
---|---|---|
标准输入(stdin) | 0 | 通常是键盘,也可以是其他文件或者命令的输出的内容可以作为标准输入 |
标准输出(stdout) | 1 | 默认输出到屏幕 |
错误输出(stderr) | 2 | 默认输出到屏幕 |
文件名称(filename) | 3+ |
-
当进程操作一个文件时:
- 首先程序是无法直接访问硬件,需要借助内核来访问文件
- 而内核kernel需要利用文件描述(file descriptor)来访问
-
总结:进程使用文件描述符来管理打开的文件对应关系
-
通常程序访问一个文件至少会打开三个标准文件,分别是标准输入,标准输出,错误输出
-
进程将从标准输入中的到数据,将正常输出打印至屏幕终端,将错误的输出信息也打印至屏幕终端
输入输出符号及作用
名称 | 符号 | 作用 |
---|---|---|
标准输入重定向 | <或者0< | 将符号右边的内容交给符号左边的命令 |
标准输出覆盖重定向 | >或者1> | 将原本要输出在屏幕上的正确内容,覆盖到重定向的文件中 |
标准输出追加重定向 | >>或者1>> | 将原本要输出在屏幕上的正确内容,追加到重定向的文件中 |
错误输出覆盖重定向 | 2> | 将原本要输出在屏幕上的错误内容,覆盖到重定向的文件中 |
错误输出追加重定向 | 2>> | 将原本要输出在屏幕上的错误内容,追加到重定向的文件中 |
案例1:标准输出覆盖重定向
- 标准输出重定向示例
- 如果文件不存在则创建
- 如果文件存在则清空内容,后写入
[root@localhost ~]# ifconfig eth0 > abc
案例2:标准输出追加重定向
- 标准输出重定向示例
- 如果文件不存在则创建
- 如果文件存在则在文件尾部添加内容
[root@localhost ~]# echo "This is network conf" >> if
案例3:错误输出重定向
- 错误输出重定向示例
- 正确输出及错误输出至相同文件
- 正确输出及错误输出至不同的文件
[root@localhost ~]#find /etc -name "*.conf" 1>ok 2>error
案例4:混合和输出重定向
- 错误输出重定向示例
- 将正确输出和错误输出混合至同一文件
- 将两个文件内容组合为一个文件
#将标准输出和标准错误输出重定向到同一个文件, 混合输出
1.[root@localhost ~]# find /etc -name "*.conf" &>ab
2.[root@localhost ~]# find /etc -name "*.conf" >ab 2>&1
#合并两个文件内容至一个文件
[root@localhost ~]# cat a b > c
案例5:将内容输出至黑洞
[root@localhost ~]# ls /root/error>ab 2>/dev/null
[root@localhost ~]# ls /root/error>ab &>/dev/null
案例6:输入重定向
1.
#没有改变输入的方向,默认键盘,此时等待输入
[root@localhost ~]# grep 'root'
xxx
xxx
[root@localhost ~]# grep 'root' < /etc/passwd
root:x:0:0:root:/root:/bin/bash
2.
[root@localhost ~]# dd if=/dev/zero of=/file1.txt bs=1M count=20
[root@localhost ~]# dd </dev/zero >/file2.txt bs=1M count=20
案例7:利用重定向建立多行的文件
[root@localhost ~]# vim fruit.sh
#!/bin/sh
menu(){
cat <<EOF
+------------+
| 1 | apple |
+---+--------+
| 2 | pear |
+---+--------+
| 3 | banana |
+---+--------+
| 4 | cherry |
+---+--------+
EOF
read -p "please input a num: " fruit
}
usage(){
echo "USAGE:请输入水果编号"
exit 1
}
color(){
case "$fruit" in
1)
echo -e "\E[1;31mapple \E[0m"
;;
2)
echo -e "\E[1;20mpear \E[0m"
;;
3)
echo -e "\E[1;33mbanana \E[0m"
;;
4)
echo -e "\E[1;35mcherry \E[0m"
;;
*)
usage
esac
}
menu
color
输入输出过程检测
#持续追踪查看文件内容
[root@localhost ~]# tail -f /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
lw:x:1000:1000::/home/lw:/bin/bash
lw1:x:1001:1001::/home/lw1:/bin/bash
oldboy:x:615:1002::/home/oldboy:/bin/bash
^Z (ctrl+z 将进程转到后台)
[1]+ Stopped tail -f /etc/passwd
#查看运行的进程
[root@localhost ~]# ps
PID TTY TIME CMD
8217 pts/1 00:00:00 bash
8258 pts/1 00:00:00 tail
8259 pts/1 00:00:00 ps
#查看8258进程下的文件描述符
[root@localhost ~]# ls -l /proc/8258/fd
total 0
lrwx------. 1 root root 64 Apr 13 19:25 0 -> /dev/pts/1
lrwx------. 1 root root 64 Apr 13 19:25 1 -> /dev/pts/1
lrwx------. 1 root root 64 Apr 13 19:25 2 -> /dev/pts/1
lr-x------. 1 root root 64 Apr 13 19:25 3 -> /etc/passwd
lr-x------. 1 root root 64 Apr 13 19:25 4 -> anon_inode:inotify
# Linux查看标准输入输出设备
[root@localhost ~]# ls -l /dev/std*
lrwxrwxrwx 1 root root 15 Dec 2 22:30 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Dec 2 22:30 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Dec 2 22:30 /dev/stdout -> /proc/self/fd/1
补充:Linux重定向&符
$ command > file 2>&1
$ command >> file 2>&1
这里的&没有固定的意思
放在>后面的&,表示重定向的目标不是一个文件,而是一个文件描述符。
换言之 2>1 代表将stderr重定向到当前路径下文件名为1的regular file中,而2>&1代表将stderr重定向到文件描述符为1的文件(即/dev/stdout)中,这个文件就是stdout在file system中的映射
而&>file是一种特殊的用法,也可以写成>&file,二者的意思完全相同,都等价于
>file 2>&1
进程管道技术
什么是管道
- 管道操作符“ | ”,主要用来连接左右两个命令,将左侧的命令的标准输出,交给右侧命令的标准输入
- 注意事项:无法传递标准错误输出至后者命令
格式
cmd1 | cmd2 […| cmdn]
管道使用范例
范例1
将/etc/passwd中的UID大小排序
[root@localhost ~]# sort -t ":" -k3 -n /etc/passwd
[root@localhost ~]# sort -t ":" -k3 -n /etc/passwd -r
[root@localhost ~]# sort -t":" -k3 -n /etc/passwd|head
范例2
打印当前所有IP
[root@localhost ~]# ip ad | grep "inet " | awk '{print $2}'|awk -F "/" '{print $1}'
127.0.0.1
10.0.0.9
tee与xarge
管道中使用tee
[root@localhost ~]# ip ad | grep "inet " | tee ip.txt|awk -F "/" '{print $1}'|awk '{print $2}'
127.0.0.1
10.0.0.9
[root@localhost ~]# cat ip.txt
inet 127.0.0.1/8 scope host lo
inet 10.0.0.9/24 brd 10.0.0.255 scope global dynamic ens33
重定向与tee有他们在使用过程中的区别
#直接将内容写入date.txt文件中
[root@localhost ~]# date > date.txt
# 命令执行会输出至屏幕,但会同时保存一份至date.txt文件中
[root@localhost ~]# date |tee date.txt
2021年 12月 06日 星期一 19:18:40 CST
[root@localhost ~]# cat date.txt
2021年 12月 06日 星期一 19:18:40 CST
管道中使用xargs
- xargs参数传递,主动让一些不支持管道的命令可以使用管道技术
[root@localhost ~]# which cat | xargs ls -l
-rwxr-xr-x. 1 root root 54160 10月 31 2018 /usr/bin/cat
[root@localhost ~]# ls | xargs rm -fv
Comments | NOTHING