4 Linux文件系统
4.1 目录结构
4.1.1 文件系统的目录结构
- 文件系统从根目录下开始,用“/”表示,根文件系统(rootfs):root filesystem
- 标准Linux文件系统(如ext4),文件名称大小写敏感,严格区分大小写
- 以 . 开头的文件为隐藏文件
- 文件名最长255个字节
包括路径在内文件名称最长4095个字节 -
蓝色-->目录
绿色-->可执行文件
红色-->压缩文件
浅蓝色-->链接文件
灰色-->其他文件 - 除了斜杠和NUL,所有字符都有效???????????、
- 每个文件都有两类相关数据:
元数据(属性):metadata
数据(内容): data
Linux的文件系统分层结构标准:FHS Filesystem Hierarchy Standard
参考文档:http://www.pathname.com/fhs/ 其中对每个文件目录有详细说明
4.1.2 常见目录功能
/ :根目录,最顶级目录,也是管理员的家目录
/boot:引导文件、内核文件(vmlinuz)、引导加载器(bootloader, grub)都存放于此
/bin:所有用户使用的基本命令(二进制文件)
/sbin:管理类的基本命令(仅由root执行)
/bin与/sbin:不能关联至独立分区,OS启动即会用到的程序
/etc 配置文件目录
/home/USERNAME:各个用户家目录,存放用户数据
/proc: 用于输出内核与进程信息相关的虚拟文件系统
/sys:用于输出当前系统上硬件设备相关信息虚拟文件系统
/usr: universal shared, read-only data(通用只读文件)
lib:32位使用
lib64:只存在64位系统
include: C程序的头文件(header files)
share:结构化独立的数据,例如doc, man等
local:第三方应用程序的安装位置
bin, sbin, lib, lib64, etc, share
/var: variable data files(可变数据)
cache: 应用程序缓存数据目录
lib: 应用程序状态信息数据
local:专用于为/usr/local下的应用程序存储可变数据
lock: 锁文件
log: 日志目录及文件
opt: 专用于为/opt下的应用程序存储可变数据
run: 运行中的进程相关数据,通常用于存储进程pid文件
spool: 应用程序数据池
tmp: 保存系统两次重启之间产生的临时数据
/dev:设备文件及特殊文件存储位置
/tmp:临时文件存储位置
/srv:系统上运行的服务用到的数据
/media:便携式移动设备挂载点(优盘)
/mnt:临时文件系统挂载点
/opt:第三方应用程序的安装位置
注意:CentOS 7 以后版本目录结构变化(以下两者相同)
/bin 和 /usr/bin
/sbin 和 /usr/sbin
/lib 和/usr/lib
/lib64 和 /usr/lib64
范例:
[root@CentOS8 data]#ls /bin /sbin /lib /lib64 -ld
lrwxrwxrwx. 1 root root 7 May 11 2019 /bin -> usr/bin
lrwxrwxrwx. 1 root root 7 May 11 2019 /lib -> usr/lib
lrwxrwxrwx. 1 root root 9 May 11 2019 /lib64 -> usr/lib64
lrwxrwxrwx. 1 root root 8 May 11 2019 /sbin -> usr/sbin
4.1.3 应用程序的组成部分:
二进制程序:/bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin
库文件: /lib, /lib64, /usr/lib, /usr/lib64, /usr/local/lib, /usr/local/lib64
配置文件: /etc, /etc/DIRECTORY, /usr/local/etc
帮助文件: /usr/share/man, /usr/share/doc, /usr/local/share/man, /usr/local/share/doc
4.1.4 Linux下的文件类型
用 ll 命令查看首字母:
(-) 普通文件
d 目录文件
b 块设备
c 字符设备
l 符号链接文件
p 管道文件pipe
s 套接字文件socket
4.2 文件操作命令
4.2.1显示当前工作目录 pwd
每个shell和系统进程都有一个当前的工作目录(current work directory,简称CWD)
显示当前shell CWD的绝对路径:使用pwd命令(printing working directory)
- -L 显示链接路径(默认)
- -P 显示真实物理路径
范例:
[root@CentOS8 bin]#pwd
/bin
[root@CentOS8 bin]#pwd -P
/usr/bin
4.2.2 绝对和相对路径@@@
[图片上传失败...(image-8b8689-1596285623724)]
绝对路径
以正斜线开始 /
完整的文件的位置路径
可用于指定任何一个文件名-
相对路径
不以斜线开始
指定相对于当前工作目录的位置
(特殊情况也可能是相对其他目录,比如创建软链接!)
可以作为一个简短的形式指定一个文件名[root@CentOS8 /]#cd etc #当前目录为/ ,因为/下有etc目录,因此可以切换到etc [root@CentOS8 etc]#cd etc #当前目录为etc,由于etc下没有名为etc的文件或目录,因此切换失败 -bash: cd: etc: No such file or directory
根据上面插图进行举例:
#假设用户当前所在的目录是 cat,而此时要切换到 dog 目录 绝对:/home/dog 相对:../dog #..表示当前目录的父目录(此处..=/home)
相对目录的优点:
有一个目录的路径为/cluster/raid/output/c.biancheng.net/cyuyan 另一个目录的路径为/cluster/raid/output/c.biancheng.net/python 此时如果要从第一个目录切换到第二个目录 使用相对路径:../python即可直接到位 #需要注意,某些复杂情况下,相对路径容易出错,而绝对路径是肯定无问题的!
#特别地: . 即表示当前目录
基名:basename,只取文件名而不要路径
目录名:dirname,只取路径,不要文件名
范例:
[root@CentOS8 ~]#basename /etc/sysconfig/network
network
[root@CentOS8 ~]#dirname /etc/sysconfig/network
/etc/sysconfig
4.2.3 更改目录 cd@@
命令 cd : change directory 改变目录(可以使用绝对或相对路径)
选项:-P 切换至物理路径
[root@CentOS8 ~]#cd /bin
[root@CentOS8 bin]#pwd
/bin
[root@CentOS8 bin]#cd -P /bin
[root@CentOS8 bin]#pwd
/usr/bin
切换至父目录: cd ..
切换至当前用户家目录: cd
切换至上一个工作目录: cd -
相关的环境变量:
PWD:当前目录路径
OLDPWD:上一次目录路径
4.2.4 列出目录内容ls
ls [options] [files_or_dirs]
#常见选项:
-a 包含隐藏文件
-l 显示额外的信息(ls -l=ll)
-R 目录递归
-ld目录和符号链接信息
-F 在末尾显示类型符号 #实用
-1 文件分行显示(#数字1)
-S 按从大到小排序 #实用
-t 按mtime排序
-u 配合-t选项,显示并按atime从新到旧排序
-U 按目录存放顺序显示
-X 按文件后缀排序
4.2.5 查看文件状态 stat
文件相关信息:metadata(属性,元数据), data(数据内容)
每个文件有三个时间戳:(touch创建已存在的文件时,刷新3个时间戳)
access time 访问时间,atime,读取文件内容
modify time 修改时间,mtime,改变文件内容(数据)
change time 改变时间,ctime,元数据发生改变(属性)
mtime的改变必然引起ctime的改变
执行ll命令默认显示mtime
4.2.6 确定文件内容/类型 file
file [options] <filename>...
#常用选项:
-b 列出文件辨识结果时,不显示文件名称
-f filelist 列出文件filelist中文件名的文件类型
-F 使用指定分隔符号替换输出文件名后默认的”:”分隔符
-L 查看对应软链接对应文件的文件类型
范例:
#将windows10上文本默认的编码转换成UTF-8
[15:34:50 root@centos8 ~]#iconv -f gb2312 win.txt -o win2.txt
[15:34:50 root@centos8 ~]#file linux.txt
linux.txt: ASCII text
[15:34:31 root@centos8 ~]#file windows.txt
windows.txt: ASCII text, with CRLF line terminators
#将windows的文本格式转换成Linux的文本格式
[15:35:26 root@centos8 ~]#dos2unix windows.txt
dos2unix: converting file windows.txt to Unix format...
[15:36:00 root@centos8 ~]#file windows.txt
windows.txt: ASCII text
#将Linux的文本格式转换成windows的文本格式
[15:36:02 root@centos8 ~]#unix2dos windows.txt
unix2dos: converting file windows.txt to DOS format...
[15:36:10 root@centos8 ~]#file windows.txt
windows.txt: ASCII text, with CRLF line terminators
file -f #同时显示多个文件格式
[15:33:05 root@centos8 ~]#cat list.txt
/etc/
/bin
/etc/issue
[15:34:28 root@centos8 ~]#file -f list.txt
/etc/: directory
/bin: symbolic link to usr/bin
/etc/issue: ASCII text
4.2.7 文件通配符 wildcard
用来匹配符合条件的多个文件,方便批理管理文件
通配符采有特定的符号,表示特定的含义,此特符号称为元字符
* 匹配零个或多个字符 #不能匹配隐藏文件!!!!!!
? 匹配任何单个字符
~ 当前用户家目录
~jack 用户jack家目录 对应命令为 cd ~jack
. 当前工作目录
~- 前一个工作目录 对应命令 cd - 或者 ll ~-/dir
[0-9] 匹配单个数字
[a-z] 字母
[A-Z] 字母
[jack] 匹配列表中的任何的一个字符,j/a/c/k任何一个
[^jack] 匹配列表中的所有字符以外的字符,排除法
范例:只显示文件夹
[16:49:27root@CentOS8data]#ls -d /etc/*/
/etc/alsa/ /etc/hp/ /etc/rc2.d/
/etc/alternatives/ /etc/init.d/ /etc/rc3.d/
/etc/audit/ /etc/insights-client/ /etc/rc4.d/
/etc/authselect/ /etc/iproute2/ /etc/rc5.d/
/etc/avahi/ /etc/iscsi/ /etc/rc6.d/
/etc/bash_completion.d/ /etc/issue.d/ /etc/rc.d/
......
别外还有在Linux系统中预定义的字符类:命令man 7 glob可以查看
[:digit:] 任意数字,相当于0-9
[:lower:] 任意小写字母,表示 a-z
[:upper:] 任意大写字母,表示 A-Z
[:alpha:] 任意大小写字母
[:alnum:] 任意数字或字母
[:blank:] 水平空白字符
[:space:] 水平或垂直空白字符
[:punct:] 标点符号
[:print:] 可打印字符
[:cntrl:] 控制字符(非打印字符)
[:graph:] 图形字符
[:xdigit:]十六进制字符
使用以上通配符,需要双重中括号!!!!!!!!!!!!!!
{a..e} 与 [a - e] 排序内容不相同!!!
[16:42:57root@CentOS8data]#touch file{A..E}.txt
[16:43:07root@CentOS8data]#touch file{a..e}.txt
[16:43:14root@CentOS8data]#touch file{1..9}.txt
[16:43:22root@CentOS8data]#ls
file1.txt file4.txt file7.txt filea.txt fileB.txt filed.txt fileE.txt
file2.txt file5.txt file8.txt fileA.txt filec.txt fileD.txt
file3.txt file6.txt file9.txt fileb.txt fileC.txt filee.txt
[16:43:25root@CentOS8data]#ls file[[:digit:]].txt
file1.txt file3.txt file5.txt file7.txt file9.txt
file2.txt file4.txt file6.txt file8.txt
[16:43:56root@CentOS8data]#ls file[[:upper:]].txt
fileA.txt fileB.txt fileC.txt fileD.txt fileE.txt
[16:44:09root@CentOS8data]#ls file[[:lower:]].txt
filea.txt fileb.txt filec.txt filed.txt filee.txt
[16:44:15root@CentOS8data]#ls file{b..d}.txt
fileb.txt filec.txt filed.txt
[16:45:12root@CentOS8data]#ls file[b-d].txt
fileb.txt fileB.txt filec.txt fileC.txt filed.txt
# {b..d}按照ASCII码排序
# [b-d] 按照 小大小大... 排序!!!!!!!!!
范例:
-
显示/etc目录下所有以 r 开头,以一个小写字母结尾,且中间出现至少一位数字的文件或目录
[root@CentOS8etc]#ls r*[[:digit:]]*[[:lower:]] rc0.d: rc1.d: rc2.d: rc3.d: rc4.d: rc5.d: rc6.d:
-
显示/etc/目录下所有以rc开头,并后面是0-6之间的数字,其它为任意字符的文件或目录
[15:48:46root@CentOS8etc]#ls rc[0-6]*
-
显示/etc目录下,所有.conf结尾,且以m,n,r,p开头的文件或目录
[15:49:39root@CentOS8etc]#ls /etc/[mnrp]*.conf man_db.conf mtools.conf nfsmount.conf pbm2ppa.conf radvd.conf resolv.conf mke2fs.conf nfs.conf nsswitch.conf pnm2ppa.conf request-key.conf rsyslog.conf
-
只显示/root下的隐藏文件和目录
#本题考点为:通配符 * 不匹配隐藏文件!!! [19:19:52root@CentOS8~]#ls -da .* . .bash_logout .cache .dbus .lesshst .tcshrc .. .bash_profile .config .esd_auth .local .viminfo .bash_history .bashrc .cshrc .ICEauthority .pki .Xauthority
-
只显示/etc下的非隐藏目录
[19:21:18root@CentOS8~]#ls -d /etc/*/ /etc/alsa/ /etc/hp/ /etc/rc2.d/ /etc/alternatives/ /etc/init.d/ /etc/rc3.d/ /etc/audit/ /etc/insights-client/ /etc/rc4.d/ /etc/authselect/ /etc/iproute2/ /etc/rc5.d/ /etc/avahi/ /etc/iscsi/ /etc/rc6.d/ /etc/bash_completion.d/ /etc/issue.d/ /etc/rc.d/ ...........
4.2.8 创建或刷新文件 touch
touch [OPTION]... FILE...
选项说明:
-a 仅改变 atime和ctime
-m 仅改变 mtime和ctime
-t [[CC]YY]MMDDhhmm[.ss] 指定atime和mtime的时间戳
-c 如果文件不存在,则不予创建
范例:创建一个以昨天日期命名的.log文件
[16:11:50 root@centos8 data]#date
Fri Dec 13 16:11:55 CST 2019
[16:11:03 root@centos8 data]#touch `date -d "-1 day" +%F_%T`.log
[16:11:48 root@centos8 data]#ls
2019-12-12_16:11:48.log
4.2.9 复制文件和目录 cp
cp 命令格式:
cp [OPTION]... [-T] SOURCE DEST 常用
cp [OPTION]... SOURCE... DIRECTORY 常用
cp [OPTION]... -t DIRECTORY SOURCE...
#常用选项
-i 覆盖前提示(默认值)
-n 不覆盖,注意两者顺序?
-b 若目标存在,覆盖前先备份,形式为 filename~
--backup=numbered 目标存在,覆盖前先备份加数字后缀
-u 只复制更加新的文件 #文件更新,旧文件默认不进行
-r, -R 递归复制目录及内部的所有内容
-v --verbose #显示文件复制过程
-d --no-dereference --preserv=links 不复制原文件,只复制链接名
-p 等同 --preserv=mode,ownership,timestamp #保留权限、所有者、时间戳
-a 归档,相当于-pr --preserv=all #保留所有元数据
cp 复制操作 | 目标不存在 | 存在且为文件 | 存在且为目录 |
---|---|---|---|
源 = 单个文件 | 新建目标并填充 | 覆盖目标 | 新建同名文件并填充 |
源 = 多个文件 | error | error | 新建全部源文件并填充 |
源 = 目录<br />(必须加 -R) | 新建同名目录并填充 | error | 新建同名子目录并填充 |
默认cp=cp -i,提示是否覆盖
范例:
1、将/etc/目录下所有文件,备份到/data独立的子目录下,并要求子目录格式为 backupYYYY-mm-dd,备份过程可见
[root@centos8 ~]#cp -av /etc/ /data/backup`date +%F`
2、创建/data/rootdir目录,并复制/root下所有文件到该目录内,要求保留原有权限
[root@CentOS8 data]#cp -a /root /data/rootdir
[root@CentOS8 data]#ls
rootdir
4.2.10 移动和重命名 mv
mv 命令可以实现文件或目录的移动和改名:
mv [OPTION]... fileA fileB #改名
mv [OPTION]... file DIR #移动
mv [OPTION]... -t DIRECTORY SOURCE...
常用选项:
-i 交互式
-f 强制
-b 若目标存在,覆盖前先备份
利用rename 可以批量修改文件名:
rename [options] <expression> <replacement> <file>...
范例:(改名对象打不打引号都可以)
#为所有的conf文件加上.bak后缀:rename 'conf' 'conf.bak' f*
[root@CentOS8 data]#touch f{1..5}.conf
[root@CentOS8 data]#ls
f1.conf f2.conf f3.conf f4.conf f5.conf
[root@CentOS8 data]#rename 'conf' 'conf.bak' f*
[root@CentOS8 data]#ls
f1.conf.bak f2.conf.bak f3.conf.bak f4.conf.bak f5.conf.bak
#去掉所有的bak后缀:rename '.bak' '' *.bak
[root@CentOS8 data]#ls
f1.conf.bak f2.conf.bak f3.conf.bak f4.conf.bak f5.conf.bak
[root@CentOS8 data]#rename .bak '' *
[root@CentOS8 data]#ls
f1.conf f2.conf f3.conf f4.conf f5.conf
4.2.11 删除文件 rm
使用rm 命令可以删除文件
rm [OPTION]... FILE...
常用选项:
-i 交互式
-f 强制删除
-r 递归,对目录进行操作时必须使用
--no-preserve-root 用来删除根目录
rm -rf /* #此命令不需要确认,执行即开始删除,无法挽回
范例:删除特殊文件
#将名为 “/data/-f” 的文件删除
rm -f -f 此方式错误!
rm -- -f
rm ./-f #相对路径写法
rm /data/-f #绝对路径写法
rm虽然删除了文件,但是被删除的文件仍然可能被恢复,
在安全要求较高的场景下,可以使用shred安全删除文件
shred [OPTION]... FILE...
常见选项:
-z 最后一次覆盖添加0,以隐藏覆盖操作
-v 能够显示操作进度
-u 覆盖后截断并删除文件
-n # 指定覆盖文件内容的次数为#(默认值是3次)
[root@CentOS8 ~]#touch passwd
[root@CentOS8 ~]#echo passwd
passwd
[root@CentOS8 ~]#shred -zvun 5 passwd
shred: passwd: removing
shred: passwd: renamed to 000000
shred: 000000: renamed to 00000
shred: 00000: renamed to 0000
shred: 0000: renamed to 000
shred: 000: renamed to 00
shred: 00: renamed to 0
shred: passwd: removed
补充技巧:防止rm造成严重后果,定义别名进行备份 (修改配置文件永久有效)
配置文件目录:/root/.bashrc
[root@CentOS8 data]#alias rm='DIR=/data/backup`date +%F_%T`;mkdir $DIR;mv -t $DIR'
[root@CentOS8 data]#rm f1.log
[root@CentOS8 data]#ls
backup2020-07-06_14:03:03 dir f2.log f3.log
4.2.12 目录操作
显示目录树 tree
常见选项:
-d: 只显示目录
-L level: 指定显示的层级数目
-P pattern: 只显示由指定wild-card pattern匹配到的路径
- 创建目录mkdir
常见选项:
-p: 存在于不报错,且可自动创建所需的各目录(用于一次创建多层目录)
-v: 显示详细信息
-m MODE: 创建目录时直接指定权限!!!!!!!!!!
- 删除空目录rmdir
rmdir只能删除空目录,如果想删除非空目录,可以使用rm -r 命令递归删除目录树
常见选项:
-p 递归删除父空目录
-v 显示详细信息
练习
(1) 如何创建/testdir/dir1/x, /testdir/dir1/y, /testdir/dir1/x/a, /testdir/dir1/x/b, /testdir/dir1/y/a,
/testdir/dir1/y/b
[17:25:08root@CentOS8dir1]#mkdir -p /data/testdir/dir1/{x,y}/{a,b}
[17:26:25root@CentOS8dir1]#tree /data/testdir/
/data/testdir/
└── dir1
├── x
│?? ├── a
│?? └── b
└── y
├── a
└── b
7 directories, 0 files
(2) 如何创建/testdir/dir2/x, /testdir/dir2/y, /testdir/dir2/x/a, /testdir/dir2/x/b
[17:26:49root@CentOS8dir1]#mkdir -p /data/testdir/dir2/{x/{a,b},y}
[17:28:06root@CentOS8dir1]#tree ../dir2
../dir2
├── x
│ ├── a
│ └── b
└── y
(3) 如何创建/testdir/dir3, /testdir/dir4, /testdir/dir5, /testdir/dir5/dir6, /testdir/dir5/dir7
[17:28:59root@CentOS8~]#mkdir -pv /data/testdir/dir{3,4,5/{6,7}}
mkdir: created directory '/data/testdir/dir3'
mkdir: created directory '/data/testdir/dir4'
mkdir: created directory '/data/testdir/dir5'
mkdir: created directory '/data/testdir/dir5/6'
mkdir: created directory '/data/testdir/dir5/7'
[17:29:54root@CentOS8~]#tree /data/testdir/
/data/testdir/
├── dir1
│ ├── x
│ │ ├── a
│ │ └── b
│ └── y
│ ├── a
│ └── b
├── dir2
│ ├── x
│ │ ├── a
│ │ └── b
│ └── y
├── dir3
├── dir4
└── dir5
├── 6
└── 7
4.3 文件元数据和节点表结构
4.3.1 inode表结构
inode = (index node)
每个文件的属性信息,比如:文件的大小,时间,类型等,称为文件的元数据
这些元数据存放在inode表中
inode 表中有很多条记录组成,第一条记录保存元数据,包括以下信息:
inode number 节点号(身份证号)
文件类型
权限
UID
GID
链接数(指向这个文件名路径名称个数)
该文件的大小和不同的时间戳
指向磁盘上文件的数据块指针
有关文件的其他数据
一般情况下inode表会占用系统磁盘inode总量的1%
[root@CentOS8/data]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 119043 389 118654 1% /dev
tmpfs 122639 1 122638 1% /dev/shm
tmpfs 122639 558 122081 1% /run
tmpfs 122639 17 122622 1% /sys/fs/cgroup
/dev/sda2 52428800 52895 52375905 1% /
/dev/sda1 65536 307 65229 1% /boot
/dev/sda5 26214400 6 26214394 1% /data
tmpfs 122639 5 122634 1% /run/user/0
- inode number 节点号
节点号表示文件的唯一编号!!!整个系统中节点号是有限的
当节点号用尽时,即使还有储存空间,也会提示无剩余空间!!!!!!
[root@CentOS8 ~]#df -i /boot
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 65536 309 65227 1% /boot
[root@CentOS8 ~]#mkdir /boot/test
[root@CentOS8 ~]#touch /boot/test/file{1..65226}
[root@CentOS8 ~]#touch /boot/test/new.txt
touch: cannot touch '/boot/test/new.txt': No space left on device
[root@CentOS8 ~]#df -i /boot
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 65536 65536 0 100% /boot
- 目录
目录是个特殊文件,目录的元数据保存了目录中文件的列表及节点号的对应关系!!!
系统引用文件是使用 inode号
实际用户是通过文件名来引用一个文件
目录是 目录下的文件名和文件inode号之间的映射
常见命令底层原理
执行cp命令:
- 分配一个空闲的inode号,在inode表中生成新条目
在目录中创建一个目录项,将名称与inode编号关联
拷贝数据生成新的文件
执行rm 命令:
- 链接数递减,从而释放的inode号可以被重用
把数据块放在空闲列表中
删除目录项
数据实际上不会马上被删除,但当另一个文件使用数据块时将被覆盖
执行mv命令:
- 如果mv命令的目标和源在同一个分区,作为mv 命令(修改指针方向即可)
用新的文件名创建对应新的目录项
删除旧目录条目对应的旧的文件名
不影响inode表(除时间戳)或磁盘上的数据位置:没有数据被移动! - 如果目标和源不在同一个分区, mv相当于先rm再cp(数据确实发生了移动)
4.3.2 硬链接 ln
硬链接本质上就给一个文件起一个新的名称,实质是同一个文件
ln filename [linkname]
范例:对文件f1.log创建新的名称f1link.log,两者inode都是132
[root@CentOS8 data]#ll -i
total 0
132 -rw-r--r--. 1 root root 0 Jul 6 09:51 f1.log
133 -rw-r--r--. 1 root root 0 Jul 6 09:51 f2.log
134 -rw-r--r--. 1 root root 0 Jul 6 09:51 f3.log
135 -rw-r--r--. 1 root root 0 Jul 6 09:51 f4.log
136 -rw-r--r--. 1 root root 0 Jul 6 09:51 f5.log
[root@CentOS8 data]#ln f1.log linkf1.log
[root@CentOS8 data]#ll -i
total 0
132 -rw-r--r--. 2 root root 0 Jul 6 09:51 f1.log
133 -rw-r--r--. 1 root root 0 Jul 6 09:51 f2.log
134 -rw-r--r--. 1 root root 0 Jul 6 09:51 f3.log
135 -rw-r--r--. 1 root root 0 Jul 6 09:51 f4.log
136 -rw-r--r--. 1 root root 0 Jul 6 09:51 f5.log
132 -rw-r--r--. 2 root root 0 Jul 6 09:51 linkf1.log
硬链接特性:
- 创建硬链接会增加额外的记录项以引用文件
- 对应于同一文件系统上同一个物理文件
- 每个目录引用相同的inode号
- 创建时链接数递增
- 删除文件时:rm命令递减计数的链接(每个链接相互独立,删除不影响文件)
只要文件存在,至少有一个链接数;当链接数为零时,该文件被删除 - 不能跨越驱动器或分区
- 不支持对目录创建硬链接
目录的链接数至少为2,因为目录中的 . 即为自身
创建子目录会导致链接数增加!
[root@CentOS8 data]#mkdir dir
[root@CentOS8 data]#ls
dir
[root@CentOS8 data]#ll -i
total 0
132 drwxr-xr-x. 2 root root 6 Jul 6 10:09 dir
[root@CentOS8 data]#ls dir -a
. .. # .即为自身 ..为父目录
[root@CentOS8/data]# mkdir dir/ddd
[root@CentOS8/data]# ll
total 4
drwxr-xr-x. 3 root root 17 Jul 31 20:53 dir #创建子目录,增加为3
4.3.3 符号链接(软链接)
一个符号链接指向另一个文件,就像windows中的快捷方式
ln -s filename [linkname]
软链接特点:
-
软链接文件大小 6 byte 表示源文件的文件名字符长度为6 byte
[root@CentOS8/data]# ll total 4 -rw-r--r--. 1 root root 23 Jul 31 20:33 abc.txt #文件名长7byte drwxr-xr-x. 3 root root 17 Jul 31 20:53 dir -rw-r--r--. 1 root root 0 Jul 31 21:03 f1 #文件名长2byte [root@CentOS8/data]# ln -s abc.txt abc.link [root@CentOS8/data]# ln -s f1 f1.link [root@CentOS8/data]# ll total 4 lrwxrwxrwx. 1 root root 7 Jul 31 21:04 abc.link -> abc.txt #7byte -rw-r--r--. 1 root root 23 Jul 31 20:33 abc.txt drwxr-xr-x. 3 root root 17 Jul 31 20:53 dir -rw-r--r--. 1 root root 0 Jul 31 21:03 f1 lrwxrwxrwx. 1 root root 2 Jul 31 21:04 f1.link -> f1 #2byte
-
可以对目录创建软链接
[root@CentOS8 data]#ln -s dir dir_link [root@CentOS8 data]#ll total 4 drwxr-xr-x. 2 root root 6 Jul 6 10:09 dir lrwxrwxrwx. 1 root root 3 Jul 6 10:22 dir_link -> dir
-
可以跨分区的文件实现
[root@CentOS8 data]#ln -s /etc etc_link [root@CentOS8 data]#ll total 4 drwxr-xr-x. 2 root root 6 Jul 6 10:09 dir lrwxrwxrwx. 1 root root 3 Jul 6 10:22 dir_link -> dir lrwxrwxrwx. 1 root root 4 Jul 6 10:24 etc_link -> /etc
-
不增加或减少目标文件的 链接数(inode引用计数)
[root@CentOS8/data]# ll -i total 4 131 -rw-r--r--. 1 root root 23 Jul 31 20:33 abc.txt #链接数为1 132 -rw-r--r--. 1 root root 0 Jul 31 21:03 f1 [root@CentOS8/data]# ln -s abc.txt link1 [root@CentOS8/data]# ln -s f1 link2 [root@CentOS8/data]# ll -i total 4 131 -rw-r--r--. 1 root root 23 Jul 31 20:33 abc.txt #链接数仍然是1 132 -rw-r--r--. 1 root root 0 Jul 31 21:03 f1 133 lrwxrwxrwx. 1 root root 7 Jul 31 21:08 link1 -> abc.txt 134 lrwxrwxrwx. 1 root root 2 Jul 31 21:08 link2 -> f1
易错点!重点概念!
-
创建软链接时,如果源文件使用相对路径,应该是相对于链接文件所在目录的路径,而非相对于当前目录
[root@CentOS8 data]#ln -s f2.log /root/f2.log.link #源文件使用相对pwd路径,错误! [root@CentOS8 data]#ll !* ll -s f2.log /root/f2.log.link 0 -rw-r--r--. 1 root root 0 Jul 6 10:32 f2.log 0 lrwxrwxrwx. 1 root root 6 Jul 6 10:50 /root/f2.log.link -> f2.log #此处报错! [root@CentOS8 data]#ln -s ../data/f2.log /root/f2.log.link2 #重写相对路径 #上述../data的意思:..相对于/root即为根,合起来../data即为相对于后者达到此处的相对路径 [root@CentOS8 data]#ll !* ll -s ../data/f2.log /root/f2.log.link2 0 -rw-r--r--. 1 root root 0 Jul 6 10:32 ../data/f2.log 0 lrwxrwxrwx. 1 root root 14 Jul 6 10:53 /root/f2.log.link2 -> ../data/f2.log
-
删除目录的软链接: rm -rf dir_link
(若后方加斜线则删除链接目录下的内容)
[root@CentOS8 data]#cd /dir
[root@CentOS8 dir]#touch xx{1..3}.log
[root@CentOS8 dir]#ls
xx1.log xx2.log xx3.log
[root@CentOS8 dir]#cd ..
[root@CentOS8 data]#ls
dir dir_link f1.log f2.log f3.log
[root@CentOS8 data]#rm -rf dir_link/ #此操作删除了软链接目录下的文件内容!
[root@CentOS8 data]#ls dir/
[root@CentOS8 data]#ll dir/
total 0
[root@CentOS8 data]#ls
dir dir_link f1.log f2.log f3.log
[root@CentOS8 data]#rm -rf dir_link #此操作才能删除软链接!!!(内部数据不变)
[root@CentOS8 data]#ls
dir f1.log f2.log f3.log
4.3.4 软硬链接区别总结
软链接 | 硬链接 | |
---|---|---|
本质 | 是快捷方式 | 是同一文件 |
文件属性 | l 链接文件 | 同源文件 |
inode编号 | 不同 | 同源文件 |
创建或删除链接后 | inode引用计数不变 | inode引用计数变化 |
删除源文件后 | 死链接 | 不影响 |
能否跨分区创建 | 能跨分区 | 不能跨分区 |
能否对目录创建 | 支持目录 | 不支持目录 |
源文件使用相对路径 | 是相对链接的路径 | 是相对自己的路径 |
关于源文件相对路径:只有跨分区创建软链接时才有此问题!
4.3.5 典型案例
案例一:
提示空间不足 No space left on device,但是 df 查看磁盘空间剩余很多
[root@CentOS8/data]# df -i /boot/
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 65536 307 65229 1% /boot
[root@CentOS8/data]# mkdir /boot/test
[root@CentOS8/data]# touch /boot/test/kkk{1..65228}
[root@CentOS8/data]# touch /boot/test/new1.txt
touch: cannot touch '/boot/test/new1.txt': No space left on device
[root@CentOS8/data]# df /boot/ #储存空间剩余很多
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 999320 108176 822332 12% /boot
[root@CentOS8/data]# df -i /boot/ #节点号已占用100%
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 65536 65536 0 100% /boot
案例二:
提示储存空间不足,删除无用的大文件后,空间并未释放,什么原因?如何解决?
#原因是大文件正在被其他程序占用!
解决:
#若知道是哪个文件
#在不能关闭程序的情况下,可以将该文件数据清空
[root@localhost ~]# > file (此方式只适用于bash)
[root@localhost ~]# cat /dev/null > file (此方式适用所有shell)
#或者命令lsof file 查看文件正在被哪个程序占用,并杀掉该进程
#若不知道是什么文件
#查找出那些 已经删除但是继续占用内存空间的文件:
lsof -n | grep deleted
4.4 标准输入和输出
读入数据:Input
输出数据:Output
打开的文件都有一个fd : file descriptor (文件描述符)
Linux给程序提供三种 I/O 设备
- 标准输入(STDIN) -0 默认接受来自终端窗口的输入
- 标准输出(STDOUT)-1 默认输出到终端窗口
- 标准错误(STDERR) -2 默认输出到终端窗口
[root@CentOS8 data]#ll /dev/std*
lrwxrwxrwx. 1 root root 15 Jul 3 23:42 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx. 1 root root 15 Jul 3 23:42 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx. 1 root root 15 Jul 3 23:42 /dev/stdout -> /proc/self/fd/1
#查看输入输出作用在哪个终端
[root@CentOS8 data]#ll /proc/self/fd
total 0
lrwx------. 1 root root 64 Jul 6 14:16 0 -> /dev/pts/2
lrwx------. 1 root root 64 Jul 6 14:16 1 -> /dev/pts/2
lrwx------. 1 root root 64 Jul 6 14:16 2 -> /dev/pts/2
#0.1.2全部指向/dev/pts/2,表示输入输出都在当前终端
[root@CentOS8 data]#tty
/dev/pts/2
4.5 I/O重定向redirect
I/O重定向:将默认的输入,输出或错误对应的设备进行修改,指向新的目标
4.5.1 标准输出和错误重新定向
STDOUT和STDERR可以被重定向到指定文件,而非默认的当前终端
cmd 操作符号 文件名 #不一定支持所有shell!!!!
支持的操作符号包括:
1==普通用法(1> 或 >)
把STDOUT重定向到文件或其他终端
重定向到文件时,若文件不存在则创建,若文件存在则覆盖内容
再次重定向到同一文件,内容再次覆盖
[root@CentOS8 data]#tty
/dev/pts/2
[root@CentOS8 data]#ls
backup2020-07-06_14:03:03 dir f2.log f3.log
[root@CentOS8 data]#ls > /dev/pts/0 #重定向到终端
[root@CentOS8 data]#
[root@CentOS8 data]#ls > /data/list.txt #重定向到文件
[root@CentOS8 data]#cat list.txt
backup2020-07-06_14:03:03
dir
f2.log
f3.log
list.txt
若 > 符号之前不输入命令,则效果为生成空文件或清空目标文件
是迅速清空文件内容的一种方式
[root@CentOS8 data]#> ./list.txt
[root@CentOS8 data]#cat list.txt
[root@CentOS8 data]#
借助/dev/null也可实现同样的功能
[root@CentOS8 data]#cat /dev/null > ./f1.txt
[root@CentOS8 data]#ll
total 0
-rw-r--r--. 1 root root 0 Jul 6 14:38 f1.txt
磁盘空间不足时,大文件被占用不能停,而且rm删除无法立即腾出空间,应使用 > 或/dev/null >
2==普通用法(2>)
把STDERR重定向到文件或其他终端
[root@CentOS8/data]# xxx
-bash: xxx: command not found
[root@CentOS8/data]# xxx 2> t.txt
[root@CentOS8/data]# cat t.txt
-bash: xxx: command not found
3==不同类型一起输出(&>或>&)
-
把所有输出重定向到同一个文件(包括stdout和stderr)
[root@CentOS8 data]#ls /data/ /xxx &> all.log [root@CentOS8 data]#cat all.log ls: cannot access '/xxx': No such file or directory /data/: all.log stderr.log stdout.log #还有其他2种思路都可实现: [root@CentOS8 data]#ls /data/ /xxx > all.log 2>&1 #注意此处是>&而不是&> [root@CentOS8 data]#ls /data/ /xxx 2> all.log 1>&2
-
把stdout和stderr分别重定向到不同文件
[root@CentOS8 data]#ls /data/ /xxx > stdout.log 2> stderr.log [root@CentOS8 data]#cat stdout.log /data/: stderr.log stdout.log [root@CentOS8 data]#cat stderr.log ls: cannot access '/xxx': No such file or directory
-
为某些特殊命令提供隐蔽功能(如改密码)
[root@CentOS8/data]# passwd jacklee >& /dev/null #执行命令后连续盲打输入两次密码,修改成功,屏幕无提示信息!!!
4==追加内容避免覆盖(>>或2>>)
[root@CentOS8/data]# who > tt.txt
[root@CentOS8/data]# cat tt.txt
root pts/0 2020-07-31 20:19 (10.0.0.1)
[root@CentOS8/data]# ll >> tt.txt
[root@CentOS8/data]# cat tt.txt
root pts/0 2020-07-31 20:19 (10.0.0.1)
total 4
-rw-r--r--. 1 root root 50 Aug 1 09:15 tt.txt
[root@CentOS8 data]#xxx 2> test.txt
[root@CentOS8 data]#cat test.txt
bash: xxx: command not found...
Failed to search for file: Cannot update read-only repo
[root@CentOS8 data]#yyy 2>> test.txt
[root@CentOS8 data]#cat test.txt
bash: xxx: command not found...
Failed to search for file: Cannot update read-only repo
bash: yyy: command not found...
Failed to search for file: Cannot update read-only repo
5==禁止覆盖(set -C)与强制覆盖(>|)
set - C 命令, 禁止将内容覆盖已有文件,但可追加(此时>|可以强制覆盖)
set + C 命令,允许覆盖
[root@CentOS8/data]# w > tt.txt
[root@CentOS8/data]# cat tt.txt
09:17:07 up 13:02, 1 user, load average: 0.06, 0.03, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 10.0.0.1 Fri20 1.00s 0.24s 0.00s w
[root@CentOS8/data]# set -C #禁止覆盖
[root@CentOS8/data]# df /data/ > tt.txt
-bash: tt.txt: cannot overwrite existing file
[root@CentOS8/data]# set +C #解锁
[root@CentOS8/data]# df /data/ > tt.txt
[root@CentOS8/data]# cat tt.txt
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda5 52403200 398632 52004568 1% /data
强制覆盖
[root@CentOS8/data]# cat tt.txt
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda5 52403200 398632 52004568 1% /data
[root@CentOS8/data]# set -C
[root@CentOS8/data]# hostname > tt.txt
-bash: tt.txt: cannot overwrite existing file
[root@CentOS8/data]# hostname >| tt.txt
[root@CentOS8/data]# cat tt.txt
CentOS8
6==多个命令合并输出
用 ( )或者{ }合并多个命令的out或err,注意使用花括号的格式!!!
[root@CentOS8 data]#(who ; hostname) > all.log
[root@CentOS8/data]# cat all.txt
root pts/0 2020-07-31 20:19 (10.0.0.1)
CentOS8
[root@CentOS8/data]# (ls;xxx) >& all.txt #同时输出不能覆盖已有文件!!!
-bash: all.txt: cannot overwrite existing file
[root@CentOS8/data]# (ls;xxx) >& all.log
[root@CentOS8/data]# cat all.log
all.log
all.txt
tt.txt
-bash: xxx: command not found
[root@CentOS8/data]# {ls;ll} >> bc.txt #第一步未留空格,命令结尾无;号
-bash: {ls: command not found
-bash: ll}: command not found
[root@CentOS8/data]# {ls;ll;} >> bc.txt #第一步未留空格
-bash: syntax error near unexpected token `}'
[root@CentOS8/data]# { ls;ll} >> bc.txt #命令结尾无;号
> ^C
[root@CentOS8/data]# { ls;ll;} >> bc.txt #正确格式!!!!!!!!
[root@CentOS8/data]# cat bc.txt
all.log
all.txt
bc.txt
tt.txt
total 16
-rw-r--r--. 1 root root 53 Aug 1 09:26 all.log
-rw-r--r--. 1 root root 58 Aug 1 09:24 all.txt
-rw-r--r--. 1 root root 30 Aug 1 09:30 bc.txt
-rw-r--r--. 1 root root 8 Aug 1 09:21 tt.txt
4.5.2 标准输入的重定向
使用 < 来重定向标准输入:从文件中导入STDIN,代替当前终端的输入设备
使用 单行或多行重定向 来创建新文件,并输入指定内容
1==基础用法:
同时存在 < > ,优先进行 输入运算
[root@CentOS8 ~]#echo 2*5 > bc.log
[root@CentOS8 ~]#bc < bc.log
10
[root@CentOS8 ~]#bc < bc.log > bc2.log #先输入至bc运算再重定向到bc2
[root@CentOS8 ~]#cat bc2.log
10
[root@CentOS8 ~]#bc > bc3.log < bc.log #先输入再输出,> 输出重定向可写在前!!!
[root@CentOS8 ~]#cat bc3.log
10
2==单行重定向
只能对新文件进行!!!!!
[root@centos8 ~]#cat > cat.log (cat.log必须是不存在的文件)
line1
line2
line3
按ctrl+C/D结束 #每次回车即为一次重定向
[root@centos8 ~]#cat cat.log
line1
line2
line3
3==多行重定向:
只能对新文件进行!!!!!
使用 "<<终止词" 命令把接下来输入的多行内容进行重定向,
直到终止词位置之前的所有文本都发送给STDIN
终止词可以是任何一个或多个符号,
比如:!,@,$,EOF(End Of File),magedu等,其中EOF比较常用
[root@CentOS8 ~]#cat > cat.log <<@ #注意使用格式!!!
> asdf
> sdfd
> ggh
> @
>
> @ #前后带空格也不行!!!!!!!
> @
[root@CentOS8 ~]#
#以上内容已经全部输入文件cat.log
4.5.3 tr 转换和删除字符
易错点:tr命令实现的是单个字符一一对应的转换关系!!!!
[root@CentOS8/~]# touch ctest{file,dir,disk}
[root@CentOS8/~]# ls
ctestdir ctestdisk ctestfile
[root@CentOS8/~]# ls | tr "test" "good"
cdooddir
cdooddiok
cdoodfilo
#想要整体替换test为good而不影响其他单个字符,须使用rename!!!
基本格式:
tr [OPTION]... SET1 [SET2]
选项:
-c :取字符集的补集
-d :删除所有#属于第一字符集的字符
常用功能:tr -dc 'abc' #意思是除了abc之外任何字符都删除!!!!!!
-s :把连续重复的字符以单独一个字符表示,即去重(连续重复的)
-t :将第一个字符集对应字符转化为第二字符集对应的字符
1==基础的转换功能:
[root@CentOS8 ~]#tr 123 abc #按对应位置替换字符
123456123456
abc456abc456
11122233
aaabbbcc
[root@CentOS8 ~]#tr 1234 abc #c替换34
123456123456
abcc56abcc56
[root@CentOS8 ~]#tr 123456 abc #c替换3456
12345678
abcccc78
-t --truncate-set1: #严格按照一一对应来替换
[root@CentOS8 ~]#tr -t 123456 abc
123456
abc456
常见用途:全局大小写转换
[root@CentOS8 ~]#tr 'a-z' 'A-Z' #批量大小写转换
sdfhfdnhsgfngfds
SDFHFDNHSGFNGFDS
#删除fstab文件中所有 含有abc的 字符
tr –d abc < /etc/fstab
2==删除指定字符
-d 删除所有含有SET1的字符
[root@CentOS8 ~]#tr -d ace
a11c22e33
112233
-c 取字符集的补集,即取反(一般与-d搭配使用)
[root@CentOS8 ~]#tr -dc 'abc' #意思是除了abc之外任何字符都删除,包括回车
a12b34c45cba
abccba[root@CentOS8 ~]#
#上一行是按了ctrl+D才显示结果,因为回车被当做字符删掉了,因此结果与提示符在同一行!!!
3==去重(常用压缩空格)
-s 把连续重复的单个字符以单独一个字符表示,即去重
abccba[root@CentOS8 ~]#tr -s 'abc'
abcabcabc
abcabcabc
aaabbbccc #单个连续才认为是重复!!!!
abc
#去除多余的空格
[root@CentOS8 ~]#df
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 910228 0 910228 0% /dev
tmpfs 924732 0 924732 0% /dev/shm
tmpfs 924732 17708 907024 2% /run
tmpfs 924732 0 924732 0% /sys/fs/cgroup
/dev/sda2 104806400 5572668 99233732 6% /
/dev/sda5 52403200 398588 52004612 1% /data
/dev/sda1 999320 133252 797256 15% /boot
/dev/sr0 6967726 6967726 0 100% /run/media/root/CentOS-8-BaseOS-x86_64
tmpfs 184944 16 184928 1% /run/user/42
tmpfs 184944 4 184940 1% /run/user/0
[root@CentOS8 ~]#df > df.log
[root@CentOS8 ~]#tr -s ' ' < df.log #压缩多个空格为一个
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 910228 0 910228 0% /dev
tmpfs 924732 0 924732 0% /dev/shm
tmpfs 924732 17708 907024 2% /run
tmpfs 924732 0 924732 0% /sys/fs/cgroup
/dev/sda2 104806400 5572668 99233732 6% /
/dev/sda5 52403200 398588 52004612 1% /data
/dev/sda1 999320 133252 797256 15% /boot
/dev/sr0 6967726 6967726 0 100% /run/media/root/CentOS-8-BaseOS-x86_64
tmpfs 184944 16 184928 1% /run/user/42
tmpfs 184944 4 184940 1% /run/user/0
4.6 管道
4.6.1 管道的功能(默认对error无效)
管道(使用符号“|”表示)用来连接多个命令
命令1 | 命令2 | 命令3 | …
功能说明:
- 将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
- 所有命令会在当前shell进程的子shell进程中执行
- 组合多种工具的功能
#经典用法:一键修改密码
[root@CentOS8 data]#echo jacklee | passwd --stdin jacklee
Changing password for user jacklee.
passwd: all authentication tokens updated successfully.
#隐藏修改成功的提示语!!!
[root@centos8 ~]#echo magedu | passwd --stdin wang &> /dev/null
注意:STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现,格式如下
命令1 2>&1 | 命令2
命令1 |& 命令2
因此,当不确定命令的输出结果,或者已知结果中存在error时,应该使用上述命令
[root@CentOS8 data]#ls /data/ /xxx | tr 'a-z' 'A-Z'
ls: cannot access '/xxx': No such file or directory #标准错误未生效
/DATA/:
ALL.LOG
STDERR.LOG
STDOUT.LOG
[root@CentOS8 data]#ls /data/ /xxx |& tr 'a-z' 'A-Z'
LS: CANNOT ACCESS '/XXX': NO SUCH FILE OR DIRECTORY #标准错误生效
/DATA/:
ALL.LOG
STDERR.LOG
STDOUT.LOG
4.6.2 管道中的 - 符号(接力棒)
范例:将 /home 里面的文件打包,不生成文件,而是传送到 stdout,经过管道后,
将 tar -cvf - /home 传送给后面的 tar -xvf - , 最后的这个 - 表示取前一个命令的 stdout
tar -cvf - /home | tar -xvf - #其中的-符号代替了临时文件,不需要额外创建
4.6.3 重定向到文件而且显示
利用tee命令可以既重定向到文件,又显示在屏幕
tee的功能:
- 保存不同阶段的输出
- 复杂管道的故障排除
- 同时查看和记录输出
命令1 | tee [-a] 文件名 | 命令2
#把命令1的STDOUT保存在文件中,并做为命令2的输入
#选项 -a 表示追加至文件
基本用法
[root@CentOS8/data]# echo 2*5+88 | tee bc.txt | bc
98
[root@CentOS8/data]# cat bc.txt
2*5+88
若后面不加命令2
-
文件不存在则创建
[root@CentOS8/data]# ls jack11 jack22 jack33 [root@CentOS8/data]# echo 666666666 | tee poly.txt 666666666 [root@CentOS8/data]# cat poly.txt 666666666
-
文件存在则覆盖内容(- a 则追加)
[root@CentOS8/data]# ls jack11 jack22 jack33 poly.txt [root@CentOS8/data]# cat jack11 hehe [root@CentOS8/data]# echo tttttt | tee jack11 #覆盖 tttttt [root@CentOS8/data]# cat jack11 tttttt [root@CentOS8/data]# cat jack33 hehehe [root@CentOS8/data]# echo qqq3333 | tee -a jack33 #追加 qqq3333 [root@CentOS8/data]# cat jack33 hehehe qqq3333