标准I/O重定向和管道

标准I/O重定向和管道

程序:

指令+数据

读入数据:Input

输出数据:Onutput

打开文件都有一个fd: file descriptor(文件描述符)

[root@centos8 ~]# ll /dev/std*    “/dev/stdin、/dev/stdout、/dev/stderr它们分别是各个终端字符设备的软链接”
lrwxrwxrwx. 1 root root 15 Mar 26 17:11 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx. 1 root root 15 Mar 26 17:11 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx. 1 root root 15 Mar 26 17:11 /dev/stdout -> /proc/self/fd/1
[root@centos8 ~]# 
[root@centos8 ~]# ll /proc/self/fd/*
ls: cannot access '/proc/self/fd/255': No such file or directory
lrwx------. 1 root root 64 Mar 26 17:56 /proc/self/fd/0 -> /dev/pts/0
lrwx------. 1 root root 64 Mar 26 17:56 /proc/self/fd/1 -> /dev/pts/0
lrwx------. 1 root root 64 Mar 26 17:56 /proc/self/fd/2 -> /dev/pts/0
lr-x------. 1 root root 64 Mar 26 17:56 /proc/self/fd/3 -> /var/lib/sss/mc/passwd
lrwx------. 1 root root 64 Mar 26 17:56 /proc/self/fd/4 -> 'socket:[53663]'
lr-x------. 1 root root 64 Mar 26 17:56 /proc/self/fd/5 -> /var/lib/sss/mc/group
[root@centos8 ~]# 
[root@centos8 ~]# ll /proc/`pidof tail` /fd
ls: cannot access '/fd': No such file or directory
/proc/:
total 0
dr-xr-xr-x.  9 root           root                         0 Mar 26 17:11 1
dr-xr-xr-x.  9 root           root                         0 Mar 26 17:11 10
dr-xr-xr-x.  9 gdm            gdm                          0 Mar 26 17:11 1017
dr-xr-xr-x.  9 gdm            gdm                          0 Mar 26 17:11 1046
dr-xr-xr-x.  9 gdm            gdm                          0 Mar 26 17:11 1079
dr-xr-xr-x.  9 gdm            gdm                          0 Mar 26 17:11 1080
dr-xr-xr-x.  9 root           root                         0 Mar 26 17:11 11
dr-xr-xr-x.  9 gdm            gdm                          0 Mar 26 17:11 1103
dr-xr-xr-x.  9 gdm            gdm                          0 Mar 26 17:11 1129
dr-xr-xr-x.  9 root           root                         0 Mar 26 17:11 114
dr-xr-xr-x.  9 root           root                         0 Mar 26 17:11 115
dr-xr-xr-x.  9 root           root                         0 Mar 26 17:11 116

Linux给程序提供三种I/O设备

​ 标准输入(STDIN)-0 默认接受来自键盘的输入

​ 标准输出(STDOUT)-1 默认输出到终端窗口

​ 标准错误(STDERR)-2 默认输出到终端窗口

I/O重定向:

将默认的输入,输出或错误对应的设备改变,指向新的目标。

标准输出和标准错误可以被重定向到文件

STDOUT和STDERR可以被重定向到指定文件,而非默认的当前终端

格式:

命令   操作符号  文件名

支持的操作符号包括:

> :把标准输出(stdout)重定向到文件,会覆盖原文件内容
>> :把标准输出(stdout)重定向到文件,会在原有内容基础上,追加内容

2> :把标准错误(stderr)重定向到文件,会覆盖原内容
2>>:把标准错误(stderr)重定向到文件,会在原内容基础上,追加内容

&>:把所有的输出重定向到文件,不管对错都输出到指定位置,覆盖输出
&>>:把所有的输出重定向到文件,不管对错都输出到指定位置,追加输出

2>&1和&>,&>>效果一样,2>&1是老版本使用,要在最后使用,才有效果。

command >/path/toshmefile 2>&1
command>>/path/to/somefile 2>&1

理解:A和B,将A输出到B上,如果对了,就正常输出到B上,如果错误了,内容还是输出在B上

合并多个程序的标准输出:

(command ;command)>file

特例:将ll和echo shell的标准输出一起重定向到file文件中,此法只能用于标准输出,
标准错误不能使用

范例:

[root@centos8 ~]# (ll /root ; echo hello) > /data/file.txt
[root@centos8 ~]# cat /data/file.txt
total 12
-rw-------. 1 root root 1594 Mar 16 18:55 anaconda-ks.cfg
-rw-------. 1 root root 1866 Mar 26 17:28 dead.letter
-rw-r--r--. 1 root root 1749 Mar 16 19:01 initial-setup-ks.cfg
hello
[root@centos8 ~]# 

范例:标准错误重定向

[root@centos8 ~]# touch /data/f1.log
[root@centos8 ~]# touch /data/all.log
[root@centos8 ~]# rm /data/f1.log 2>/data/all.log
[root@centos8 ~]# cd /data/all.log
-bash: cd: /data/all.log: Not a directory
[root@centos8 ~]# cat /data/all.log
rm: remove regular empty file '/data/f1.log'? 
[root@centos8 ~]# y

范例:合并多个命令的结果至一个文件中

[root@centos8 ~]# ( cal 2019 ; cal 2020) > all.txt
[root@centos8 ~]# cat all.txt
                               2019                               

       January               February                 March       
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
       1  2  3  4  5                   1  2                   1  2
 6  7  8  9 10 11 12    3  4  5  6  7  8  9    3  4  5  6  7  8  9
13 14 15 16 17 18 19   10 11 12 13 14 15 16   10 11 12 13 14 15 16
20 21 22 23 24 25 26   17 18 19 20 21 22 23   17 18 19 20 21 22 23
27 28 29 30 31         24 25 26 27 28         24 25 26 27 28 29 30
                                              31        
                                2020                               

       January               February                 March       
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
          1  2  3  4                      1    1  2  3  4  5  6  7
 5  6  7  8  9 10 11    2  3  4  5  6  7  8    8  9 10 11 12 13 14
12 13 14 15 16 17 18    9 10 11 12 13 14 15   15 16 17 18 19 20 21
19 20 21 22 23 24 25   16 17 18 19 20 21 22   22 23 24 25 26 27 28
26 27 28 29 30 31      23 24 25 26 27 28 29   29 30 31     
[root@centos8 ~]# { ls ; hostname ;} > /data/all.log
[root@centos8 ~]# cat /data/all.log
all.txt
anaconda-ks.cfg
dead.letter
initial-setup-ks.cfg
centos8.magedu.org
[root@centos8 ~]# 

范例:清除大文件

cat /dev/null > /data/file.log

范例:分别重定向

[root@centos8 ~]# ls /data/   /xxx  > stdout.log 2>stderr.log

范例:将标准输出和错误都重定向到同一个文件

[root@centos8 ~]# ls /data /xxx  > /data/all.log 2>&1 
[root@centos8 ~]# ls /data /xxx  2> /data/all.log 1>&2 
[root@centos8 ~]# ls /data /xxx  &> /data/all.log  
[root@centos8 ~]# ls /data /xxx 2>&1 /data/all.log 
ls: cannot access '/xxx': No such file or directory

范例:

[root@centos8 ~]# ll /root > /data/file.txt   
[root@centos8 ~]# cat /data/file.txt
total 12
-rw-------. 1 root root 1594 Mar 16 18:55 anaconda-ks.cfg
-rw-------. 1 root root 1866 Mar 26 17:28 dead.letter
-rw-r--r--. 1 root root 1749 Mar 16 19:01 initial-setup-ks.cfg
[root@centos8 ~]# 
[root@centos8 ~]# ll /etc >> /data/file.txt
[root@centos8 ~]# cat /data/file.txt
total 12
-rw-------. 1 root root 1594 Mar 16 18:55 anaconda-ks.cfg
-rw-------. 1 root root 1866 Mar 26 17:28 dead.letter
-rw-r--r--. 1 root root 1749 Mar 16 19:01 initial-setup-ks.cfg
total 1360
-rw-r--r--.  1 root root        16 Mar 16 18:54 adjtime
-rw-r--r--.  1 root root      1518 Sep 10  2018 aliases
drwxr-xr-x.  3 root root        65 Mar 16 18:52 alsa
drwxr-xr-x.  2 root root      4096 Mar 16 18:53 alternatives
-rw-r--r--.  1 root root       541 May 11  2019 anacrontab
-rw-r--r--.  1 root root        55 May 14  2019 asound.conf
-rw-r--r--.  1 root root         1 May 11  2019 at.deny
讲ll显示的结果输出重定向到文件file中,使用>时,file文件被覆盖了,使用>>时,原文件file和重定向的内容都显示了,是追加内容。

tr命令

  • tr :转换和删除字符

  • tr [OPTION]… SET1 [SET2] ( []非必选)

  • 常用选项:
    ① -c –C –-complement:取字符集的补集
    ② -d –-delete:删除所有属于第一字符集的字符
    ③ -s –-squeeze-repeats:把连续重复的字符以单独一个字符表示
    ④ -t –-truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符

    [:alnum:]:字母和数字
    [:alpha:]:字母
    [:digit:]:数字
    [:lower:]:小写字母
    [:upper:]:大写字母
    [:space:]:空白字符
    [:print:]:可打印字符
    [:punct:]:标点字符
    [:graph:]:图形字符
    [:cntrl:]:控制(非打印)字符
    [:xdigit:]:十六进制字符
    

    范例:

    “该命令会把/etc/issue中的小写字符转化为大写字符”
    [root@centos8 ~]# tr 'a-z' 'A-Z' </etc/issue
    “删除fstab文件中的所有ABC中任意字符”
    [root@centos8 ~]# tr -d abc < /etc/fstab
    

    范例:取消空格符

    [root@centos8 ~]# df
    Filesystem     1K-blocks    Used Available Use% Mounted on
    devtmpfs          992100       0    992100   0% /dev
    tmpfs            1006652       0   1006652   0% /dev/shm
    tmpfs            1006652    9524    997128   1% /run
    tmpfs            1006652       0   1006652   0% /sys/fs/cgroup
    /dev/sda2      104806400 5510208  99296192   6% /
    /dev/sda3       52403200  398584  52004616   1% /data
    /dev/sda1         999320  116032    814476  13% /boot
    tmpfs             201328      16    201312   1% /run/user/42
    tmpfs             201328       4    201324   1% /run/user/0
    [root@centos8 ~]# df >df.log
    [root@centos8 ~]# tr -s ' ' : < df.log  
    Filesystem:1K-blocks:Used:Available:Use%:Mounted:on
    devtmpfs:992100:0:992100:0%:/dev
    tmpfs:1006652:0:1006652:0%:/dev/shm
    tmpfs:1006652:9524:997128:1%:/run
    tmpfs:1006652:0:1006652:0%:/sys/fs/cgroup
    /dev/sda2:104806400:5510208:99296192:6%:/
    /dev/sda3:52403200:398584:52004616:1%:/data
    /dev/sda1:999320:116032:814476:13%:/boot
    tmpfs:201328:16:201312:1%:/run/user/42
    tmpfs:201328:4:201324:1%:/run/user/0
    [root@centos8 ~]# 
    

    范例:将Windows的文本转化为Linux的文本格式

    [root@centos8 ~]# cat windows.txt
    a
    b
    c[root@centos8 ~]# file windows.txt
    windows.txt: ASCII text, with CRLF line terminators
    [root@centos8 ~]# hexdump -C windows.txt
    00000000  61 0d 0a 62 0d 0a 63                              |a..b..c|
    00000007
    [root@centos8 ~]# nano linux.txt
    [root@centos8 ~]# hexdump -C linux.txt
    00000000  61 20 62 20 63 0a                                 |a b c.|
    00000006
    [root@centos8 ~]# tr -d '\r' < windows.txt > windows2.txt
    [root@centos8 ~]# ls
    all.txt          dead.letter  initial-setup-ks.cfg  stderr.log  windows2.txt
    anaconda-ks.cfg  df.log       linux.txt             stdout.log  windows.txt
    [root@centos8 ~]# hexdump -C windows2.txt
    00000000  61 0a 62 0a 63                                    |a.b.c|
    00000005
    [root@centos8 ~]# file windows2.txt
    windows2.txt: ASCII text
    

标准输入重定向

  • 利用“<”可以将标准输入重定向

范例:

[root@centos8 ~]# echo 2^3 >bc.log
[root@centos8 ~]# cat bc.log
2^3
[root@centos8 ~]# bc < bc.log
8
[root@centos8 ~]#
  • cat > file

    cat > file
    hello world
    #按ctrl+d离开,可以使用文件来代替键盘的输入
    [root@centos8 ~]# cat > cat.log
    asdas da
    asda
    asd ^C
    [root@centos8 ~]# cat cat.log
    asdas da
    asda
    
  • Cat > filea < fileb

  • cat < file1 >> file1

    [root@centos8 ~]# cat < mail.txt
    hello
    how old you
    [root@centos8 ~]# cat mail.txt
    hello
    how old you
    [root@centos8 ~]# cat < mail.txt > mail2.txt
    [root@centos8 ~]# cat mail2.txt
    hello
    how old you
    [root@centos8 ~]# cat mail.txt
    hello
    how old you
    [root@centos8 ~]# mail -s 邮件主题 邮箱账号 < mail.txt
    

把多行发送给STDIN

  • 使用“<<终止词”命令从键盘把多行重导向给STDIN
  • 直到 终止词 位置的所有文本都发送给STDIN
  • 有时被称为就地文本(heretext)

管道

管道

  • 管道(使用符号\“|”表示)用来连接命令

  • command1 |command2 |command3…

  • 将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN

  • STDERR(标准错误)默认不能通过管道转发,可利用2>&1 或 |& 实现

  • 最后一个命令会在当前shell进程的子shell进程中执行用来

  • 组合多种工具的功能

范例:转换为大写字母

[root@centos8 ~]# ls | tr 'a-z' 'A-Z'

范例:less实现分页地查看输入

[root@centos8 ~]# ls -l /etc | less

范例:mail 通过电子邮件发送输入

[root@centos8 ~]# echo "test mail" | mail -s "test" 邮箱地址

范例:算数运算

echo "2^3" | bc

管道中的 - 符号

管道中有时候会使用-符号

范例:

将/homed里面的文件打包,但打包的数据不是记录到文件,而是传送到stdout,经过管道后,将tar -cvf - /home传送给后面的tar - xvf - ,后面的这个 - 则是取前一个命令的stdout ,因此,就不需要使用临时file了。

tar - cvf - /home | tar -xvf -

tee

  • 重定向到多个目标

    命令1 | tee [-a ] 文件名 | 命令2   "把command1的标准输出保存在文件中,然后管道输入给command2"
    

    ①命令1的STDOUT保存在文件中,做为命令2的输入
    ②-a 追加

  • 使用:
    ♦ 保存不同阶段的输出
    ♦ 复杂管道的故障排除
    ♦ 同时查看和记录输出

    范例:

     ls /boot | tee ls.log | tr ‘a-z’ ‘A-Z’
    

练习

  1. 将/etc/issue文件中的内容转换为大写后保存至/tmp/issue.out文件中

    cat /etc/issue | tr [a-z] [A-Z] >> /tmp/issue.out
    
  2. 将当前系统登录用户的信息转换为大写后保存至/tmp/who.out文件中

    who | tr [a-z] [A-Z] >> /tmp/who.out
    
  3. 一个linux用户给root发邮件,要求邮件标题为”help”,邮件正文如下:Hello, I am 用户名,The system version is here,please help me to check it ,thanks!操作系统版本信息

    mail -s "help" root <<EFO
    > Hello ,I am `whoami`,The system version is here,please help me to check it ,thanks!
    > `cat /etc/centos-release`
    > EFO
    
  4. 将/root/下文件列表,显示成一行,并文件名之间用空格隔开

    ls /root | tr "\n" " "
    
  5. 计算1+2+3+..+99+100的总和

    echo {1..100} | tr " " "+" | bc 
    seq -s "+" 1 100 | bc
    
  6. 删除Windows文本文件中的回车字符,‘\r字符

    yum -y install unix2dos
    dos2unix file
    unix2dos file
    
  7. 处理字符串“xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4”,只保留其中的数字和空格

    echo 'xt.,l 1 jr#clearmn 2 c*/fe 3 uz 4' | tr -dc "[0-9 ]"
    
  8. 将PATH变量每个目录显示在独立的一行

    echo $PATH | tr ":" "\n"
    
  9. 将指定文件中0-9分别替代成a-j

    tr [0-9] [a-j] < file.txt
    
  10. 将文件/etc/centos-release中每个单词(由字母组成)显示在独立一行,并无空行

    cat /etc/centos-release | tr -sc "[:alnum:]." "\n"
    
  11. 下面那一个选项结果不一样 ( B )
    A app.sh > f1.log 2>&1
    B app.sh 2>&1 > f1.log
    C app.sh 2>f1.log 1>&2
    D app.sh &>f1.log

  12. 4、在/home/stud1/wang目录下有一文件file,使用(d)可实现在后台执行命令,此命令将file中的内容输出到file.copy文件中。

    a. cat file > file.copy

    b. cat > file.copy

    c. cat file file.copy &

    d. cat file > file.copy &

  13. 如何保存linux历史命令并显示命令操作是时间?

    HISTTIMEFORMAT="%F %T " 
    
    永久生效写在/etc/profile或~/.bash_profile export HISTTIMEFORMAT="%F %T "
    

猜你喜欢

转载自www.cnblogs.com/Coolcoc/p/12578297.html