12.第三章 Linux文件管理和IO重定向

Posted Raymond2999

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了12.第三章 Linux文件管理和IO重定向相关的知识,希望对你有一定的参考价值。

4.IO 重定向和管道

4.1 标准输入和输出

程序:指令+数据

读入数据:Input

输出数据:Output

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

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

  • 标准输入(STDIN) -0 默认接受来自终端窗口的输入
  • 标准输出(STDOUT)-1 默认输出到终端窗口
  • 标准错误(STDERR) -2 默认输出到终端窗口

范例:文件描述符

[root@rocky8 ~]# ll /dev/std*
lrwxrwxrwx 1 root root 15 Oct  5 13:28 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Oct  5 13:28 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Oct  5 13:28 /dev/stdout -> /proc/self/fd/1
[root@rocky8 ~]# ll /proc/self/fd/*
ls: cannot access '/proc/self/fd/255': No such file or directory
lrwx------ 1 root root 64 Oct  5 13:51 /proc/self/fd/0 -> /dev/pts/0
lrwx------ 1 root root 64 Oct  5 13:51 /proc/self/fd/1 -> /dev/pts/0
lrwx------ 1 root root 64 Oct  5 13:51 /proc/self/fd/2 -> /dev/pts/0
lr-x------ 1 root root 64 Oct  5 13:51 /proc/self/fd/3 -> /var/lib/sss/mc/passwd
lrwx------ 1 root root 64 Oct  5 13:51 /proc/self/fd/4 -> 'socket:[26913]'
lr-x------ 1 root root 64 Oct  5 13:51 /proc/self/fd/5 -> /var/lib/sss/mc/group

4.2 I/O重定向 redirect

I/O重定向:将默认的输入,输出或错误对应的设备改变,指向新的目标

4.2.1 标准输出和错误重新定向

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

格式:

命令 操作符号 文件名

支持的操作符号包括:

1>> 把STDOUT重定向到文件
2> 把STDERR重定向到文件

&> 把标准输出和错误都重定向
>& 把标准输出和错误都重定向,即和上面功能一样,建议使用上面方式

以上如果文件已存在,文件内容会被覆盖

set -C 禁止将内容覆盖已有文件,但可追加, 利用 >| 仍可强制覆盖
set +C 允许覆盖,默认

追加

>> 可以在原有内容基础上,追加内容

把输出和错误重新定向追加到文件

>> 追加标准输出重定向至文件
2>> 追加标准错误重定向至文件

标准输出和错误输出各自定向至不同位置

COMMAND > /path/to/file.out 2> /path/to/error.out

合并标准输出和错误输出为同一个数据流进行重定向

&> 覆盖重定向
&>> 追加重定向

COMMAND > /path/to/file.out 2>&1 (顺序很重要)
COMMAND >> /path/to/file.out 2>&1

合并多个程序

(CMD1;CMD2…) 或者{ CMD1;CMD2;…; }合并多个程序的STDOUT

范例:

[root@rocky8 ~]# ll /dev/pts/0
crw--w---- 1 root tty 136, 0 Oct  5 13:56 /dev/pts/0
[root@rocky8 ~]# tty
/dev/pts/0	#/dev/pts/0 就是当前登陆的终端

[root@rocky8 ~]# ls 1> /dev/pts/1  #把输出重定向到/dev/pts/1

[root@rocky8 ~]# hostname > /dev/pts/1  #把输出信息重定向到 /dev/pts/1,>前面的1可以写,也可以不写,系统默认不用写1

范例:

[root@rocky8 ~]# who
root     pts/0        2021-10-05 13:28 (172.31.0.1)
[root@rocky8 ~]# who > who.out
[root@rocky8 ~]# cat who.out 
root     pts/0        2021-10-05 13:28 (172.31.0.1)
#把输出信息重定向到文件

[root@rocky8 ~]# ll who.out 
-rw-r--r-- 1 root root 52 Oct  5 14:04 who.out
[root@rocky8 ~]# ls >who.out
[root@rocky8 ~]# cat who.out 
anaconda-ks.cfg
who.out
[root@rocky8 ~]# ll who.out 
-rw-r--r-- 1 root root 24 Oct  5 14:05 who.out
#如果文件里有数据,再重定向,源文件数据会被覆盖

[root@rocky8 ~]# > who.out
[root@rocky8 ~]# ll who.out 
-rw-r--r-- 1 root root 0 Oct  5 14:06 who.out
#如果直接> 大于号 重定向,文件直接被清空

[root@rocky8 ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
[root@rocky8 ~]# yum -y install csh
[root@rocky8 ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/csh
/bin/tcsh
/usr/bin/csh
/usr/bin/tcsh
[root@rocky8 ~]#  /usr/bin/csh
[root@rocky8 ~]#  > who.out
Invalid null command.
#换了新的shell,它不支持> 大于号重定向
[root@rocky8 ~]# cat /dev/null > who.out #但是它支持cat /dev/null ,这种写法比较通用
[root@rocky8 ~]# exit
exit

[root@rocky8 ~]# ll /dev/null
crw-rw-rw- 1 root root 1, 3 Oct  5 13:28 /dev/null
#/dev/null 它是系统里的字符设备,就相当于空

[root@rocky8 ~]# ls > ls.out
[root@rocky8 ~]# cat ls.out 
anaconda-ks.cfg
ls.out
who.out
[root@rocky8 ~]# hostname >> ls.out
[root@rocky8 ~]# cat ls.out 
anaconda-ks.cfg
ls.out
who.out
rocky8
#>> 两个大于号是追加

[root@rocky8 ~]# touch a.log
[root@rocky8 ~]# rm a.log 
rm: remove regular empty file 'a.log'? ^C #提示信息是标准输出还是标准错误
[root@rocky8 ~]# rm a.log > f.log
rm: remove regular empty file 'a.log'? ^C #> 用标准输出还有提示
[root@rocky8 ~]# rm a.log 2> f.log #用2> 标准错误就没有提示

#新开一个终端窗口
[root@rocky8 ~]# cat f.log 
rm: remove regular empty file 'a.log'? [root@rocky8 ~]#
#现在可以看到f.log文件里已经有内容了,说明提示信息是标准错误

[root@rocky8 ~]# rm a.log 2> f.log
y #输入y
[root@rocky8 ~]# ll a.log
ls: cannot access 'a.log': No such file or directory #a.log文件被删除了

[root@rocky8 ~]# xxx
-bash: xxx: command not found
[root@rocky8 ~]# xxx 2> f.log 
[root@rocky8 ~]# cat f.log 
-bash: xxx: command not found

[root@rocky8 ~]# touch a.txt
[root@rocky8 ~]# ls a.txt
a.txt
[root@rocky8 ~]# ls a.txt xxx
ls: cannot access 'xxx': No such file or directory
a.txt
[root@rocky8 ~]# ls a.txt xxx >f1.log 2>f2.log
[root@rocky8 ~]# cat f1.log 
a.txt
[root@rocky8 ~]# cat f2.log 
ls: cannot access 'xxx': No such file or directory
#用> 和2>把标准输出和标准错误分别放到不同的文件

[root@rocky8 ~]#  ls a.txt xxx &> all.log
[root@rocky8 ~]# cat all.log 
ls: cannot access 'xxx': No such file or directory
a.txt
#&>  把标准输出和标准错误放到一个文件里

[root@rocky8 ~]# ls a.txt xxx > all2.log 2>&1
[root@rocky8 ~]# cat all2.log 
ls: cannot access 'xxx': No such file or directory
a.txt
#也可以这样同时把标准输出和标准错误放到一个文件里
#ls a.txt xxx > all2.log 2>&1 这个意思就是 > 把标准输出写到all2.log里,后面跟上2>&1 就是把标准错误也写到all2.log里

[root@rocky8 ~]# ls xyz
ls: cannot access 'xyz': No such file or directory
[root@rocky8 ~]# ls xyz 2>1
[root@rocky8 ~]# cat 1
ls: cannot access 'xyz': No such file or directory
#如果写成ls xyz 2>1,就是把标准错误写到1这个文件里,2>&1  2> 后面必须跟上&1 才能表示把标准错误也写到标准输出的文件里

[root@rocky8 ~]# ls a.txt xxx 2>&1 > all.log
ls: cannot access 'xxx': No such file or directory
[root@rocky8 ~]# cat all.log
a.txt
#换个次序不行,把标准错误屏幕上输出,没有重定向到文件,只有标准输出重定向到文件
#因为2>&1,命令执行到这里的时候并没有约定把标准错误写入到文件中,它只能再屏幕上显示,> 只是到这里把标准输出重定向到all.log文件里了,这样的写法是不对的

[root@rocky8 ~]# ls a.txt xxx 2> all2.log 1>&2
[root@rocky8 ~]# cat all2.log 
ls: cannot access 'xxx': No such file or directory
a.txt
#这样写是可以的

范例:标准错误重定向

[root@rocky8 ~]# rm /data/f1.log 2> /data/all.log

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

[root@rocky8 ~]# ( cal 2019 ; cal 2020 ) > all.txt
[root@rocky8 ~]# { ls;hostname;} > /data/all.log

范例:清除大文件

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

范例:分别重定向

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

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

[root@rocky8 ~]# ls /data /xxx > /data/all.log 2>&1
[root@rocky8 ~]# ls /data /xxx 2> /data/all.log 1>&2
[root@rocky8 ~]# ls /data /xxx &> /data/all.log

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

范例:

[root@rocky8 ~]# passwd raymond &> /dev/null

4.2.2 标准输入重定向

从文件中导入STDIN,代替当前终端的输入设备,使用 < 来重定向标准输入

某些命令能够接受从文件中导入的STDIN

4.2.2.1 标准输入重定向

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

比如:

cat > file
hello
linux

按ctrl+d离开,可以使用文件来代替键盘的输入

cat < file1 > file2
cat < file1 >> file1

范例:

[root@rocky8 ~]#  rm a.txt
rm: remove regular empty file 'a.txt'? ^C #删除时候有提示
[root@rocky8 ~]# echo y >b.txt #往b.txt里写入y
[root@rocky8 ~]# rm a.txt < b.txt  #用标准输入重定向< 小于号,代替手动输入y
rm: remove regular empty file 'a.txt'? [root@rocky8 ~]# ll a.txt
ls: cannot access 'a.txt': No such file or directory #现在文件已经被删除了

[root@rocky8 ~]# seq -s+ 1 100
1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100
[root@rocky8 ~]# seq -s+ 1 100 >seq.log
[root@rocky8 ~]# bc <seq.log
5050

[root@rocky8 ~]# cat
line1
line1
raymond
raymond
^C
#cat 命令默认 是等待输入,输入后再输出

[root@rocky8 ~]# cat > f1.txt
hello #这里只要输入什么敲入回车,都会写入到文件

#重新开一个终端窗口
[root@rocky8 ~]# cat f1.txt 
hello #现在就可以看到f1.txt里有内容

[root@rocky8 ~]# cat > f1.txt
hello
`date +%F`
$PATH
^C 
#输入一行写入一行,这叫单行重定向

[root@rocky8 ~]# cat f1.txt
hello
`date +%F`
$PATH

4.2.2.2 把多行重定向

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

其中终止词可以是任何一个或多个符号,比如:!,@,$,EOF(End Of File),magedu等,其中EOF比较常用

范例:

[root@rocky8 ~]# cat >f1.txt <<!	 #这里<< 两个小于号后边跟的终止符什么都可以,一般使用EOF
> line1
> line2
> $PATH
> `date +%F`
>  !		#!  这个终止符 再结束时,前面不能有空格或别的什么字符
> ! 		#同理后边也不能有空格或别的什么字符
> hello
> end line
> !		#必须单独的一个终止符才能结束

[root@rocky8 ~]# cat f1.txt 
line1
line2
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin		#这里就可以识别变量
2020-11-18	#命令也能识别
 !
! 
hello
end line
#这就是多行重定向

4.3 tr 命令

tr 转换和删除字符

tr [OPTION]... SET1 [SET2]

选项:

[root@rocky8 ~]# tr --help
Usage: tr [OPTION]... SET1 [SET2]
Translate, squeeze, and/or delete characters from standard input,
writing to standard output. #翻译、压缩和/或删除标准输入中的字符,写入标准输出。

  -c, -C, --complement    use the complement of SET1 #取字符集的补集
  -d, --delete            delete characters in SET1, do not translate #删除所有属于第一字符集的字符
  -s, --squeeze-repeats   replace each sequence of a repeated character
                            that is listed in the last specified SET,
                            with a single occurrence of that character #把连续重复的字符以单独一个字符表示,即去重
  -t, --truncate-set1     first truncate SET1 to length of SET2 #将第一个字符集对应字符转化为第二字符集对应的字符

SETs are specified as strings of characters.  Most represent themselves.
Interpreted sequences are:

  \\NNN            character with octal value NNN (1 to 3 octal digits)
  \\\\              backslash
  \\a              audible BEL
  \\b              backspace
  \\f              form feed
  \\n              new line #换行
  \\r              return #回车
  \\t              horizontal tab
  \\v              vertical tab
  CHAR1-CHAR2     all characters from CHAR1 to CHAR2 in ascending order
  [CHAR*]         in SET2, copies of CHAR until length of SET1
  [CHAR*REPEAT]   REPEAT copies of CHAR, REPEAT octal if starting with 0
  [:alnum:]       all letters and digits #字母和数字
  [:alpha:]       all letters #字母
  [:blank:]       all horizontal whitespace  #水平空白 
  [:cntrl:]       all control characters #控制(非打印)字符
  [:digit:]       all digits #数字
  [:graph:]       all printable characters, not including space #图形字符
  [:lower:]       all lower case letters #小写字母
  [:print:]       all printable characters, including space #可打印字符
  [:punct:]       all punctuation characters #标点符号
  [:space:]       all horizontal or vertical whitespace #空白字符
  [:upper:]       all upper case letters #大写字母
  [:xdigit:]      all hexadecimal digits #十六进制字符
  [=CHAR=]        all characters which are equivalent to CHAR

Translation occurs if -d is not given and both SET1 and SET2 appear.
-t may be used only when translating.  SET2 is extended to length of
SET1 by repeating its last character as necessary.  Excess characters
of SET2 are ignored.  Only [:lower:] and [:upper:] are guaranteed to
expand in ascending order; used in SET2 while translating, they may
only be used in pairs to specify case conversion.  -s uses the last
specified SET, and occurs after translation or deletion.

GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Full documentation at: <https://www.gnu.org/software/coreutils/tr>
or available locally via: info '(coreutils) tr invocation'

范例:

[root@rocky8 ~]# tr '123' 'abc'
ffe123fdf5f
ffeabcfdf5f
12345
abc45
^C
#把1转换成a,2转换成b,3转换成c

[root@rocky8 ~]# tr 'abc' 'ABC'
abcdef
ABCdef
^C
#把a转换成A,b转换成B,c转换成C

[root@rocky8 ~]# tr 'a-z' 'A-Z'
fdjkfjdkfjdkl
FDJKFJDKFJDKL
^C
#把小写转换成大写

[root@rocky8 ~]# tr 'abc' '1234'
abcdef
123def
^C
#前面字符比后边少会一一对应

[root@rocky8 ~]# tr 'abcd' '123'
abcdefg
1233efg
^C
#前面字符比后边多,前边多的会用后边最后一个替换

[root@rocky8 ~]#  tr 'abcde' '123'
abcdefg
12333fg
^C

[root@rocky8 ~]# tr -t 'abcde' '123'
abcdef
123def
^C
#-t  会一一对应转换

[root@rocky8 ~]#  tr -d 'abc'
aa2bbf45cc
2f45
^C
#-d 会删除指定的字符

[root@rocky8 ~]# tr -s 'abc'
aaabbbbbcccca
abca
^C
#-s 把连续的字符压缩

[root@rocky8 ~]#  tr 'a-z' 'A-Z' <f1.txt 
HELLO
`DATE +%F`
$PATH

[root@rocky8 ~]# echo {1..100..2}
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99
[root@rocky8 ~]# echo {1..100..2} |tr ' ' '+'
1+3+5+7+9+11+13+15+17+19+21+23+25+27+29+31+33+35+37+39+41+43+45+47+49+51+53+55+57+59+61+63+65+67+69+71+73+75+77+79+81+83+85+87+89+91+93+95+97+99
[root@rocky8 ~]# echo {1..100..2} |tr ' ' '+' |bc
2500

范例:

#该命令会把/etc/issue中的小写字符都转换成大写字符
tr ‘a-z’ ‘A-Z’< /etc/issue
#删除fstab文件中的所有abc中任意字符
tr –d abc < /etc/fstab

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

[root@rocky8 ~]# cat win.txt 
a
b
c[root@rocky8 ~]# hexdump -C win.txt
00000000  61 0d 0a 62 0d 0a 63                              |a..b..c|
00000007
[root@rocky8 ~]# tr -d '\\r' <win.txt #把文件中的回车符删除
a
b
c[root@rocky8 ~]# file win.txt
win.txt: ASCII text, with CRLF line terminators #上面并没有删除
[root@rocky8 ~]# tr -d '\\r' <win.txt >win2.txt #重定向到win2.txt文件中
[root@rocky8 ~]# file win2.txt 
win2.txt: ASCII text #现在可以看到已经是LInux文本格式
[root@rocky8 ~]# hexdump -C win2.txt
00000000  61 0a 62 0a 63                                    |a.b.c|
00000005
#文件中没有回车符了,实现了文件格式转换

思考:将 Linux 的文本转化 Windows 的文本格式 ?

4.4 管道

4.4.1 管道

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

格式

命令1 | 命令2 | 命令3 |

功能说明:

  • 将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
  • 所有命令会在当前shell进程的子shell进程中执行
  • 组合多种工具的功能

注意:STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现,格式如下

命令1 2>&1 | 命令2
命令1 |& 命令2

范例:

[root@rocky8 ~]# seq -s+ 1 100 >seq.log
[root@rocky8 ~]# bc <seq.log
5050
[root@rocky8 ~]# seq -s+ 1 100 | bc
5050
#可以用管道符 直接把前面的标准输出传给后面的标准输入

管道前面的命令必须有标准输出,后面的命令必须有标准输入才能用,不然就没有什么效果

范例:

[root@rocky8 ~]# ss -ntl
State           Recv-Q           Send-Q                     Local Address:Port                     Peer Address:Port          Process          
LISTEN          0                128                              0.0.0.0:22                            0.0.0.0:*                              
LISTEN          0                128                                 [::]:22                               [::]:* 
#查看有没有25端口在启用
[root@rocky8 ~]# yum -y install postfix
[root@rocky8 ~]#  systemctl enable --now postfix
Created symlink /etc/systemd/system/multi-user.target.wants/postfix.service → /usr/lib/systemd/system/postfix.service.

[root@rocky8 ~]# ss -ntl
State           Recv-Q           Send-Q                     Local Address:Port                     Peer Address:Port          Process          
LISTEN          0                128                              0.0.0.0:22                            0.0.0.0:*                              
LISTEN          0                100                            127.0.0.1:25                            0.0.0.0:*                              
LISTEN          0                128                                 [::]:22                               [::]:*                              
LISTEN          0                100                                [::1]:25                               [::]:*  #现在就有25端口了

[root@rocky8 ~]# mail -s test raymond
hello
i am root
. #. 点号结束
EOT

[root@rocky8 ~]# su - raymond
Last login: Sat Oct  2 22:02:21 CST 2021 on pts/0
[raymond@rocky8 ~]$ mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/raymond": 2 messages 2 new
>N  1 root                  Tue Oct  5 15:34  19/602   "test"
 N  2 root                  Tue Oct  5 15:34  19/602   "test"
& 1
Message  1:
From root@rocky8.localdomain  Tue Oct  5 15:34:37 2021
Return-Path: <root@rocky8.localdomain>
X-Original-To: raymond
Delivered-To: raymond@rocky8.localdomain
Date: Tue, 05 Oct 2021 15:33:34 +0800
To: raymond@rocky8.localdomain
Subject: test
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: root <root@rocky8.localdomain>
Status: R

hello
i am root

& exit
#可以收到邮件

[root@rocky8 ~]# mail -s test2  raymond <<EOF
> hello
> welcom to study Linux
> EOF

[raymond@rocky8 ~]$ mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/raymond": 4 messages 1 new
    1 root                  Tue Oct  5 15:34  20/613   "test"
    2 root                  Tue Oct  5 15:34  20/613   "test"
    3 Mail Delivery System  Tue Oct  5 15:42  77/2521  "Undelivered Mail Returned to Sender"
>N  4 root                  Tue Oct  5 15:44  19/615   "test2"
& 4
Message  4:
From root@rocky8.localdomain  Tue Oct  5 15:44:52 2021
Return-Path: <root@rocky8.localdomain>
X-Original-To: raymond
Delivered-To: raymond@rocky8.localdomain
Date: Tue, 05 Oct 2021 15:44:52 +0800
To: raymond@rocky8.localdomain
Subject: test2
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: root <root@rocky8.localdomain>
Status: R

hello
welcom to study Linux

[root@rocky8 ~]# cat >mail.txt <<EOF
> hello
> everyone
> EOF

[root@rocky8 ~]# cat mail.txt 
hello
everyone

[root@rocky8 ~]# mail -s test3 raymond <mail.txt

[raymond@rocky8 ~]$ mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/raymond": 5 messages 1 new
    1 root                  Tue Oct  5 15:34  20/613   "test"
    2 root                  Tue Oct  5 15:34  20/613   "test"
    3 Mail Delivery System  Tue Oct  5 15:42  77/2521  "Undelivered Mail Returned to Sender"
    4 root                  Tue Oct  5 15:44  20/626   "test2"
>N  5 raymond@rocky8.local  Tue Oct  5 15:46  19/607   "test3"
& 5
Message  5:
From raymond@rocky8.localdomain  Tue Oct  5 15:46:52 2021
Return-Path: <raymond@rocky8.localdomain>
X-Original-To: raymond
Delivered-To: raymond@rocky8.localdomain
Date: Tue, 05 Oct 2021 15:46:52 +0800
To: raymond@rocky8.localdomain
Subject: test3
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: raymond@rocky8.localdomain
Status: R

hello
everyone

[root@rocky8 ~]# ls xxx | tr 'a-z' 'A-Z'
ls: cannot access 'xxx': No such file or directory
#标准错误是不能用管道符传入到标准输入

[root@rocky8 ~]# ls xxx |& tr 'a-z' 'A-Z'
LS: CANNOT ACCESS 'XXX': NO SUCH FILE OR DIRECTORY
#用 |&  可以不管标准输出或标准错误都传给后面的命令

[root@rocky8 ~]# ls xxx 2>&1 |tr 'a-z' 'A-Z'
LS: CANNOT ACCESS 'XXX': NO SUCH FILE OR DIRECTORY
#用2>&1  这种方法也是可以的

范例:

[root@rocky8 ~]# df > df.log
[root@rocky8 ~]# tr -s ' ' < df.log
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 383024 0 383024 0% /dev
tmpfs 400580 0 400580 0% /dev/shm
tmpfs 400580 5684 394896 2% /run
tmpfs 400580 0 400580 0% /sys/fs/cgroup
/dev/sda2 104806400 2506160 102300240 3% /
/dev/sda5 52403200 398400 52004800 1% /data
/dev/sda1 1038336 173464 864872 17% /boot
tmpfs 80116 0 80116 0% /run/user/0
[root@rocky8 ~]# df | tr -s ' '
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 383024 0 383024 0% /dev
tmpfs 400580 0 400580 0% /dev/shm
tmpfs 400580 5684 394896 2% /run
tmpfs 400580 0 400580 0% /sys/fs/cgroup
/dev/sda2 104806400 2506184 102300216 3% /
/dev/sda5 52403200 398400 52004800 1% /data
/dev/sda1 1038336 173464 864872 17% /boot
tmpfs 80116 以上是关于12.第三章 Linux文件管理和IO重定向的主要内容,如果未能解决你的问题,请参考以下文章

Linux基础管理—— " 标准IO及重定向及管道 "

linux管理及IO重定向

Linux中IO重定向和管道

linux第三章--管道符,重定向和环境变量

Linux基础IO篇

文件管理和IO重定向-DAY3