Linux I/O重定向
- 标准输入(stdin):文件描述符0
- 标准输入(stdout):文件描述符1
- 标准错误(stderr):文件描述符2
file descriptors(FD,文件描述符 或 Process I/O channels);
文件描述符表
理解I/O重定向的原理需要从Linux内核为进程所维护的关键数据结构入手。对Linux进程来讲,每个打开的文件都是通过文件描述符(File Descriptor)来标识的,内核为每个进程维护了一个文件描述符表,这个表以FD为索引,再进一步指向文件的详细信息。在进程创建时,内核为进程默认创建了0、1、2三个特殊的FD,这就是STDIN、STDOUT和STDERR,如下图所示意:
所谓的I/O重定向也就是让已创建的FD指向其他文件。
进程使用文件描述符来管理打开的文件
[root@centos7-1 ~]# ls /proc/$$/fd
0 1 2 255
$$ 显示当前线程的PID
0, 1, and 2, known as standard input, standard output, and standard error
输出重定向(覆盖、追加)
- 正确输出:1> 1>> 等价于 > >>
- 错误输出:2> 2>>
小技巧:
1. # >hello.txt 可创建一个名为hello.txt的文件
案例1:输出重定向(覆盖)
[root@centos7-1 ~]# date 1> date.txt
案例2:输出重定向(追加)尾部追加
[root@centos7-1 ~]# date >> date.txt
案例3:错误输出重定向
[root@centos7-1 ~]# ls /home/ /aaaa >list.txt
ls: 无法访问/aaaa: 没有那个文件或目录
[root@centos7-1 ~]# ls /home/ /aaaa >list.txt 2>err.txt //重定向到不同的位置
案例4:正确和错误都输出到相同位置 &>
[root@centos7-1 ~]# ls /home/ /aaaa &>list.txt //混合输出
案例5:正确和错误都输出到相同位置 2>&1
[root@centos7-1 ~]# ls /home/ /aaaa >list.txt 2>&1 //重定向到相同的位置 把2重定向到1
案例6:重定向到空设备/dev/null
[root@centos7-1 ~]# ls /home/ /aaaa >list.txt 2>/dev/null //空设备,即将产生的输出丢掉
[root@centos7-1 ~]# ls /home/ /aaaa &>/dev/null //空设备,即将产生的输出丢掉
/dev/null 补充
cp /etc/passwd /dev/null ??? # 文件复制 centos7 不允许
cp /etc/passwd /etc/passwd1 2>/dev/null ???
/dev/null:是一个空设备,黑洞,任何文件都可以扔进去,但是看不见
如果/dev/null设备被删除怎么办? rm -f /dev/null
1、手动创建
# mknod -m 666 /dev/null c 1 3 # (主设备号 从设备号)
mknod [OPTION]… NAME TYPE [MAJOR MINOR]
2.重启自动,创建
# reboot
[root@centos7-1 ~]# ll /dev/null /dev/zero
crw-rw-rw- 1 root root 1, 3 11月 7 12:23 /dev/null
crw-rw-rw- 1 root root 1, 5 11月 7 12:23 /dev/zero
[root@bogon ~]# ll /dev/sda
brw-rw——. 1 root disk 8, 0 8月 16 14:11 /dev/sda
brw-rw——. 1 root disk 8, 1 8月 16 14:11 /dev/sda1
brw-rw——. 1 root disk 8, 2 8月 16 14:11 /dev/sda2
主设备号 从设备号
MAJOR MINOR
主设备号相同:表示为同一种设备类型,也可以认为keme使用的是相同的驱动
从设备号:在同一类型中的一个序号
[root@centos7-1 ~]# ll /dev/null /dev/vda1 /etc/hosts
crw-rw-rw- 1 root root 1, 3 11月 7 12:23 /dev/null
brw-rw—— 1 root disk 252, 1 11月 7 12:23 /dev/vda1
-rw-r—r—. 1 root root 172 10月 29 14:38 /etc/hosts
c表示字符设备
普通文件和设备文件的区别:
从表面上看,普通文件有大小;块设备文件没有大小,有主设备号和从设备号。
brw-rw—— 1 root disk 252, 1 11月 7 12:23 /dev/vda1
-rw-r—r—. 1 root root 172 10月 29 14:38 /etc/hosts
*字符设备和快设备的区别:
字符设备没有缓存,块设备有缓存
new.txt ???
>/etc/passwd ???
>/etc ???案例7:脚本中使用重定向
``` 案例1:脚本中使用重定向
vim ping.sh
!/usr/bin/bash
ping -c1 192.168.0.105 &>/dev/null if [ $? -eq 0 ];then echo “up..” else echo “down..” fi
chmod +x ping.sh
bash ping.sh
案例2:脚本中使用重定向
vim ping2.sh
!/usr/bin/bash
ping -c1 192.168.0.105 &>/dev/null if [ $? -eq 0 ];then echo “192.168.0.105 up..” > /up.txt else echo “192.168.0.105 down..” >/down.txt fi
chmod +x ping.sh
bash ping2.sh
<a name="3205187368"></a>
## 输入重定向
标准输入: < 等价于 0<
<a name="639004498"></a>
### 案例1
[root@centos7-1 ~]# mail -s "ssss" alice //没有改变输入的方向,默认键盘<br />111<br />222<br />333 <br />^D<br />[root@centos7-1 ~]# su - alice //切换alice查看邮件<br />[alice@centos7-1 ~]$ mail<br />Mail version 8.1 6/6/93. Type ? for help.<br />"/var/spool/mail/alice": 1 message 1 new<br />>N 1 root@tianyun.local Mon Oct 29 14:09 18/657 "ssss"<br />&
[root@centos7-1 ~]# mail -s "test01" alice < /etc/hosts //输入重定向,来自于文件 -s添加邮件主题
<a name="3314069979"></a>
### 案例2
[root@centos7-1 ~]# grep 'root' //没有改变输入的方向,默认键盘,此时等待输入...<br />yang sss<br />sssrootssss..<br />sssrootssss..
[root@centos7-1 ~]# grep 'root' < /etc/passwd<br />root:x:0:0:root:/root:/bin/bash<br />operator:x:11:0:operator:/root:/sbin/nologin
<a name="2709014240"></a>
### 案例3
[root@centos7-1 ~]# dd if=/dev/zero of=/file1.txt bs=1M count=2<br />[root@centos7-1 ~]# dd </dev/zero >/file2.txt bs=1M count=20
<a name="2572842582"></a>
### 案例4 :mysql表结构导入
[root@centos7-1 ~]# mysql -uroot -p123 < bbs.sql
<a name="A0o3t"></a>
### 案例5:at
[root@bogon ~]# at now +5 min <br />at> useradd giao<br />at> <EOT><br />job 2 at Mon Aug 17 22:09:00 2020<br />// 从现在起5分钟后创建一个user为giao的用户
[root@bogon ~]# vim a.txt<br />useradd giao1<br />useradd giao2<br />[root@bogon ~]# at now +2 min <a.txt <br />job 3 at Mon Aug 17 22:09:00 2020<br />**问题 **<br />计划任务服务<br />Can't open /var/run/atd.pid to signal atd. No atd running?<br />**已解决**<br />[root@cuixuanguo ~]# yum -y install at<br />[root@cuixuanguo ~]# chkconfig --level 35 atd on<br />[root@cuixuanguo ~]# systemctl start atd.service
<a name="210145550"></a>
### 重定向综合案例
综合案例1:利用重定向建立多行的文件
[root@centos7-1 ~]# echo “111” > file1.txt [root@centos7-1 ~]# cat file1.txt 111
[root@centos7-1 ~]# cat >file2.txt 111 222 333 444 ^D [root@centos7-1 ~]# cat file2.txt
请问:file2.txt有几行? 4行
[root@centos7-1 ~]# cat >>file3.txt aaa bbb ccc ddd ^D [root@centos7-1 ~]# cat file3.txt
请问:file3.txt有几行? 4行
[root@centos7-1 ~]# cat >file4 <<EOF
111 222 333 EOF [root@centos7-1 ~]# cat file4 111 222 333
综合案例2:利用重定向建立多行的文件 **脚本script创建多行文件**
[root@bogon ~]# vim create_file.sh cat >file200.txt <<-EOF // <<EOF 加’-‘可以识别EOF之前为了缩进而使用的tab键 111 222 333 444 555 EOF
[root@bogon ~]# chmod +x create_file.sh [root@bogon ~]# ./create_file.sh [root@bogon ~]# cat file200.txt 111 222 333 444 555
不添加执行权限
[root@bogon ~]# bash create_file.sh [root@bogon ~]# cat file200.txt 111 222 333 444 555
综合案例2: 脚本中利用重定向打印消息
[root@centos7-1 ~]# vim yang.sh
!/usr/bin/bash
cat <<-EOF
+————————————————————————+
| |
| ====================== |
| 虚拟机基本管理centos |
| |
| ====================== |
| 1. 安装虚拟机 |
| 2. 重置所有Linux虚拟机 |
| 3. 重置Windows虚拟机 |
| 4. 重置Windows虚拟机 [完全] |
| 5. 重置指定的虚拟机 |
| q. 退出管理程序 |
| |
+————————————————————————+
EOF
综合案例3
[root@centos7-1 ~]# ls; date &>/dev/null //希望两条命令输出都重定向
[root@centos7-1 ~]# ls &>/dev/null; date &>/dev/null
[root@centos7-1 ~]# (ls; date) &>/dev/null
[root@centos7-1 ~]# (while :; do date; sleep 2; done) & //在后台运行,但输出依然在终端显示 [root@centos7-1 ~]# fg ^c
[root@centos7-1 ~]# (while :; do date; sleep 2; done) &>date.txt & [1] 6595 [root@centos7-1 ~]# tailf date.txt Tue Apr 12 22:04:32 CST 2017 Tue Apr 12 22:04:34 CST 2017 Tue Apr 12 22:04:36 CST 2017 Tue Apr 12 22:04:38 CST 2017 Tue Apr 12 22:04:40 CST 2017 Tue Apr 12 22:04:42 CST 2017 Tue Apr 12 22:04:44 CST 2017 Tue Apr 12 22:04:46 CST 2017 Tue Apr 12 22:04:48 CST 2017
[root@centos7-1 ~]# jobs
[1]+ Running ( while :; do
date; sleep 2;
done ) &>date.txt &
[root@centos7-1 ~]# kill %1
[root@centos7-1 ~]# jobs
```
后面课程学习安装源码软件时:
[root@centos7-1 ~]# (./configure && make && make install ) &>/dev/null
扩展点:subshell
==当前shell中执行==
[root@bogon ~]# cd /boot; ls
config-3.10.0-1127.18.2.el7.x86_64
config-3.10.0-1127.el7.x86_64
efi
grub
grub2
initramfs-0-rescue-04d167f551d7ff44815e6c05eff9c929.img
initramfs-3.10.0-1127.18.2.el7.x86_64.img
initramfs-3.10.0-1127.el7.x86_64.img
symvers-3.10.0-1127.18.2.el7.x86_64.gz
symvers-3.10.0-1127.el7.x86_64.gz
System.map-3.10.0-1127.18.2.el7.x86_64
System.map-3.10.0-1127.el7.x86_64
vmlinuz-0-rescue-04d167f551d7ff44815e6c05eff9c929
vmlinuz-3.10.0-1127.18.2.el7.x86_64
vmlinuz-3.10.0-1127.el7.x86_64
[root@bogon boot]#
==在subshell中执行==
[root@bogon ~]# (cd /boot; ls)
config-3.10.0-1127.18.2.el7.x86_64
config-3.10.0-1127.el7.x86_64
efi
grub
grub2
initramfs-0-rescue-04d167f551d7ff44815e6c05eff9c929.img
initramfs-3.10.0-1127.18.2.el7.x86_64.img
initramfs-3.10.0-1127.el7.x86_64.img
symvers-3.10.0-1127.18.2.el7.x86_64.gz
symvers-3.10.0-1127.el7.x86_64.gz
System.map-3.10.0-1127.18.2.el7.x86_64
System.map-3.10.0-1127.el7.x86_64
vmlinuz-0-rescue-04d167f551d7ff44815e6c05eff9c929
vmlinuz-3.10.0-1127.18.2.el7.x86_64
vmlinuz-3.10.0-1127.el7.x86_64
[root@bogon ~]#
# 如果不希望某些命令的执行对当前shell环境产生影响,请在subshell中执行
[root@bogon ~]# umask
0022
[root@bogon ~]# umask 000; touch file888
[root@bogon ~]# ll file888
-rw-rw-rw-. 1 root root 0 8月 17 23:51 file888
[root@bogon ~]# umask
0000
[root@bogon ~]# umask 0022
[root@bogon ~]# (umask 000; touch file999)
[root@bogon ~]# ll file999
-rw-rw-rw-. 1 root root 0 8月 17 23:51 file999
[root@bogon ~]# umask
0022