3月14日 标准I/O和管道

1.在linux里每打开一个文件,就会响应开启一个文件描述符(fd) 例: 打开/var/log/message

[root@centos7 data]# tail -f /var/log/messages 
Mar 11 20:37:36 centos7 NetworkManager[6246]: <info>  [1552307856.6123] dhcp4 (ens33):   nameserver '192.168.172.1'
Mar 11 20:37:36 centos7 NetworkManager[6246]: <info>  [1552307856.6123] dhcp4 (ens33):   domain name 'localdomain'
Mar 11 20:37:36 centos7 NetworkManager[6246]: <info>  [1552307856.6123] dhcp4 (ens33): state changed bound -> bound
Mar 11 20:37:36 centos7 dbus[6238]: [system] Activating via systemd: service name='org.freedesktop.nm_dispatcher' unit='dbus-org.freedesktop.nm-dispatcher.service'
Mar 11 20:37:36 centos7 dhclient[19931]: bound to 192.168.172.136 -- renewal in 791 seconds.

另起一个终端,在/proc中找到tail相对应的进程,进入fd目录

[root@centos7 21099]# cd /proc/`pidof tail`/fd
[root@centos7 fd]# ll
total 0
lrwx------ 1 root root 64 Mar 11 20:42 0 -> /dev/pts/0
lrwx------ 1 root root 64 Mar 11 20:42 1 -> /dev/pts/0
lrwx------ 1 root root 64 Mar 11 20:42 2 -> /dev/pts/0
lr-x------ 1 root root 64 Mar 11 20:42 3 -> /var/log/messages   此为打开的文件,3就是文件描述符
lr-x------ 1 root root 64 Mar 11 20:42 4 -> anon_inode:inotify

在Linux中有3个标准的I/O描述符 0:标准输入:键盘输入,也可用文件输入 1:标准输出:默认输出当前端口,也可通过重定向输出至文件或其他终端。 2:错误输出:默认输出当前端口,也可通过重定向输出至文件或其他终端。

1.标准输出重定向: > 标准输出重定向在输出内容时会覆盖文件内的内容,如果要追加,需使用>>

标准输出的一些使用方法:

一、使用标准输出清空文件 使用标准输出清空文件有两种方法: 1.使用/dev/null清空文件

[root@centos7 data]# ll list.txt
-rw-r--r-- 1 root root 24 Mar 11 20:58 list.txt
[root@centos7 data]# cat /dev/null > list.txt 
[root@centos7 data]# ll list.txt
-rw-r--r-- 1 root root 0 Mar 11 20:59 list.txt

2.直接使用>清空文件

[root@centos7 data]# ll list.txt 
-rw-r--r-- 1 root root 24 Mar 11 21:02 list.txt
[root@centos7 data]# > list.txt 
[root@centos7 data]# ll list.txt
-rw-r--r-- 1 root root 0 Mar 11 21:02 list.txt

注意:使用此方法清空文件时,在某些shell中不支持

二、使用标准输出创建文件 标准输出可以创建空文件,实现方法如下: 1.使用>来创建文件

[root@centos7 data]# ls
[root@centos7 data]# > test
[root@centos7 data]# ll
total 0
-rw-r--r-- 1 root root 0 Mar 11 21:15 test

2.由于用>创建文件时,如果文件存在则会清空文件,为防止误操作,所以使用>>来创建空文件,此时即使文件存在也不会被覆盖,只会在文件后追加空行。 1.创建空文件

[root@centos7 data]# >> test
[root@centos7 data]# ll test
-rw-r--r-- 1 root root 0 Mar 11 21:24 test
2.重定向创建文件时,若文件存在:
[root@centos7 data]# ll test 
-rw-r--r-- 1 root root 17 Mar 11 21:28 test
[root@centos7 data]# > test
[root@centos7 data]# ll test
-rw-r--r-- 1 root root 0 Mar 11 21:28 test   文件被清空

若要在使用标准输出时,文件不被覆盖可以使用以下设置 1.set -C :无法覆盖,但可以追加。但使用>|符号时扔可强制覆盖

[root@centos7 data]# set -C
[root@centos7 data]# echo "hello word" > test       
-bash: test: cannot overwrite existing file         无法覆盖
[root@centos7 data]# echo "hello word" >| test      强制覆盖
[root@centos7 data]# cat test
hello word
[root@centos7 data]# echo "hello word" >> test      追加
[root@centos7 data]# cat test
hello word
hello word

2.set +C :可以覆盖。

[root@centos7 data]# echo "hi" > test
-bash: test: cannot overwrite existing file
[root@centos7 data]# set +C
[root@centos7 data]# echo hi > test
[root@centos7 data]# echo test
test

标准错误重定向使用方法: 将错误输出至文件内

[root@centos7 data]# ls -a
.  ..
[root@centos7 data]# ls /error
ls: cannot access /error: No such file or directory
[root@centos7 data]# ls /error 2> error.log
[root@centos7 data]# cat  error.log 
ls: cannot access /error: No such file or directory

既有正确又有错误输出时合并重定向使用方法:

  1. right error > /path/to/file 2>&1 把标准输出输出到file,再把错误输出的转变为标准输出一起输出到file
[root@centos7 /]# ls /data /error  > /data/test 2>&1 
[root@centos7 /]# cat /data/test
ls: cannot access /error: No such file or directory
/data:
right
test
  1. right error 2> /path/to/file >&2 把错误输出输出到file,再把标准输出转变为错误输出一起输出到file
[root@centos7 /]# ls /data /error  2> /data/test >&2 
[root@centos7 /]# cat /data/test 
ls: cannot access /error: No such file or directory
/data:
right
test

3.right error &> /path/to/file 把正确的输出和错误的输出一起输出到 file

[root@centos7 /]# ls /data /error  &> /data/test
[root@centos7 /]# cat /data/test 
ls: cannot access /error: No such file or directory
/data:
right
test

多条命令的执行结果存入一个文件内需要使用()

[root@centos7 data]# (hostname;uname -r) > file2
[root@centos7 data]# cat file2
centos7.localdomain
3.10.0-957.el7.x86_64

所以以下写法也能实现合并正确和错误输出 4.(right error 2>&1)> /path/to/file 将错误输出转换为正确的一起输出至file

[root@centos7 data]# (ls /data /error 2>&1) > /data/file
[root@centos7 data]# cat /data/file
ls: cannot access /error: No such file or directory
/data:
file

5.(right error >&2) 2> /path/to/file 将正确输出转换为错误的一同输出至file

[root@centos7 data]# (ls /data /error >&2) 2> /data/file
[root@centos7 data]# cat /data/file 
ls: cannot access /error: No such file or directory
/data:
file

单行重定向 单行重定向是将内容逐行传输给一个文件 cat > file

多行重定向 多行重定向是先输入每一行的内容然后一起定向到一个文件内 cat << eof > file 其中eof为文件结束符

示例:

[root@centos7 ~]# cat << eof > file1
> hello word
> $HOSTNAME
> eof
[root@centos7 ~]# cat file1
hello word
centos7.localdomain

管道 | 管道就是将前一项命令的结果当作后一项命令的输入

[root@centos7 data]# echo abc | tr a-z A-Z
ABC

管道无法实现将错误命令结果也传递到后一项命令中要实现的话需要使用|&符号

[root@centos7 data]# asdf sdf | tr a-z A-Z
bash: asdf: command not found...
Similar command is: 'sadf'
[root@centos7 data]# asdf sdf |& tr a-z A-Z
BASH: ASDF: COMMAND NOT FOUND...
SIMILAR COMMAND IS: 'SADF'

Tee命令: 命令格式: tee [OPTION]... [FILE]... 说明: 从标准输入读取数据分别输出至标准输出和文件中

选项 说明
-a 追加

示例: 1

[root@centos7 data]# echo {a..d} | tee test
a b c d
[root@centos7 data]# cat test
a b c d

2.tee命令默认在输出结果保存至文件中是会覆盖上一次的内容可以使用-a进行追加操作

[root@centos7 data]# cat test
a b c d
[root@centos7 data]# echo {1..3} | tee test
1 2 3
[root@centos7 data]# cat test
1 2 3
[root@centos7 data]# echo {a..d} | tee -a test
a b c d
[root@centos7 data]# cat test
1 2 3
a b c d

tr命令: 命令格式:

   tr [OPTION]... SET1 [SET2]

说明: 转换或删除字符

选项 说明
-t 对位替换
-d 删除
-c 取反
-s 压缩

示例: 1.当SET1比SET2位数多时,SET1最后一位自动替换SET2的最后一位

[root@centos7 ~]# tr 'abcd' '123'
abcdd
12333

2.要防止上述情况发生可以使用-t选项对位替换

[root@centos7 ~]# tr -t 'abcd' '123'
abcddd
123ddd

3.-d对被SET1匹配中的内容进行删除

[root@centos7 ~]# tr -d 'abc'
abcde
de

4.-c将除SET1以外的内容替换成SET2,在使用-c时需要用ctrl+d来执行

[root@centos7 ~]# tr -c 'abc' 'd'
abcdefg
abcddddd[root@centos7 ~]# 

配合-d可以实现删除除了SET1之外的字符

5.-s将连续且相同的字符压缩

[root@centos7 ~]# tr -s 'abc'
aaaaaaaaabbbbbbbccccccccdabd
abcdabd

6.在使用tr命令时还能使用通配符的方法进行替换

[root@centos7 ~]# echo "abcdef" > test
[root@centos7 ~]# tr '[:lower:]' '[:upper:]' < test
ABCDEF
[root@centos