文件系统目录结构
FHS文件系统
FHS(Filesystem Hierarchy Standard:文件系统层次化标准),是由Linux基金会维护的,帮助发行版 厂商和开发者们使用共同的标准来约定其发行的Linux系统或开发的软件遵守共同的文件和目录标准。
FHS是多数Linux版本采用的文件组织形式,采用树形结构组织文件。FHS定义了系统中每个区域的用 途、所需要的最小构成的文件和目录,同时还给出了例外处理与矛盾处理。
文件系统的目录结构
-
文件和目录被组织成一个单根倒置树结构
-
文件系统从根目录下开始,用“/”表示
-
根文件系统(rootfs):root filesystem
-
标准Linux文件系统(如:ext4),文件名称大小写敏感,例如:MAIL, Mail, mail, mAiL
-
以 . 开头的文件为隐藏文件 路径分隔的 /
-
文件名最长255个字节 包括路径在内文件名称最长4095个字节
-
蓝色-->目录 绿色-->可执行文件 红色-->压缩文件 浅蓝色-->链接文件 灰色-->其他文件
-
除了斜杠和NUL,所有字符都有效,但使用特殊字符的目录名和文件不推荐使用,有些字符需要用 引号来引用
-
每个文件都有两类相关数据:元数据:metadata,即属性, 数据:data,即文件内容
常见的文件系统目录功能
/boot #引导文件存放目录,内核文件(vmlinuz)、引导加载器(bootloader, grub)都存放
于此目录
/bin #所有用户使用的基本命令;不能关联至独立分区,OS启动即会用到的程序
/sbin #管理类的基本命令;不能关联至独立分区,OS启动即会用到的程序
/lib #启动时程序依赖的基本共享库文件以及内核模块文件(/lib/modules)
/lib64 #专用于x86_64系统上的辅助共享库文件存放位置
/etc #配置文件目录
/home/USERNAME #普通用户家目录
/root #管理员的家目录
/media #便携式移动设备挂载点
/mnt #临时文件系统挂载点
/dev #设备文件及特殊文件存储位置, b:block device,随机访问,c:character
device,线性访问
/opt #第三方应用程序的安装位置
/srv #系统上运行的服务用到的数据
/tmp #临时文件存储位置
/usr #universal shared, read-only data
/usr/bin #保证系统拥有完整功能而提供的应用程序
/usr/sbin #同上
/usr/lib #32位使用
/usr/lib64 #只存在64位系统
/usr/include #C程序的头文件(header files)
/usr/share #结构化独立的数据,例如doc, man等
/var #variable data files,可变数据目录
/var/cache #应用程序缓存数据目录
/var/lib #应用程序状态信息数据
/var/local #专用于为/usr/local下的应用程序存储可变数据
/var/lock #锁文件
/var/log #日志目录及文件
/var/opt #专用于为/opt下的应用程序存储可变数据
/var/run #运行中的进程相关数据,通常用于存储进程pid文件
/var/spool #应用程序数据池
/var/tmp #保存系统两次重启之间产生的临时数据
/proc #用于输出内核与进程信息相关的虚拟文件系统
/sys #用于输出当前系统上硬件设备相关信息虚拟文件系统
/selinux #security enhanced Linux,selinux相关的安全策略等信息的存储位置
应用程序的组成部分
不同类型文件常用的目录
文件类型 | 常用目录 |
---|---|
二进制文件 | /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 |
新版本目录结构变化
-
/bin 和 /usr/bin
-
/sbin 和 /usr/sbin
-
/lib 和 /usr/lib
-
/lib64 和 /usr/lib64
Linux下的文件类型
文件类型 | 标识符 | 说明 |
---|---|---|
普通文件 | - | |
目录文件 | d | directory |
符号链接文件 | l | link |
块设备文件 | b | block |
字符设备文件 | c | character |
管道文件 | p | pipe |
套接字文件 | s | socket |
Linux 系统中的文件类型颜色标识
Linux 系统中,每种颜色,都有对应的含义,可以根据文件在终端中显示的颜色,来判断是什么类型的文 件
颜色与文件类型对应关系,由配置文件定义,可更改(此处的文件类型,可以理解为文件格式)
vim /etc/DIR_COLORS
文件类型(格式) | 颜色 |
---|---|
普通文件 | 白色 |
目录文件 | 蓝色 |
符号链接文件 | 浅蓝色 |
块设备文件 | 黄色 |
字符设备文件 | 黄色 |
管道文件 | 青黄色 |
套接字文件 | 粉红色 |
图片文件 | 粉红色 |
压缩文件或文件包 | 红色 |
可执行文件 | 绿色 |
其他文件 | 灰色 |
管道文件
所谓管道,是指用于连接一个读进程和一个写进程,以实现它们之间通信的共享文件,又称 pipe 文件。
套接字文件
Socket本身有“插座”的意思,在Unix/Linux环境下,用于表示进程间网络通信的特殊文件类型。本质为 内核借助缓冲区形成的伪文件。
文件操作命令
显示当前工作目录
每个shell和系统进程都有一个当前的工作目录 CWD:current work directory
显示当前shell CWD的绝对路径
pwd命令: printing working directory
pwd [-LP]
#常用选项
-P #显示真实物理路径
-L #显示链接路径(默认)
绝对和相对路径
描述一个文件位置有两种方式
绝对路径
-
以正斜杠/ 即根目录开始
-
描述完整的文件的位置路径
-
可用于任何想指定一个文件名的时候
相对路径
-
不以斜线开始,而是以当前所在的位置开始
-
一般情况下,是指相对于当前工作目录的路径,特殊场景下,是相对于某目录的位置
-
可以作为一个简短的形式指定一个文件名
基名 & 目录名
基名:basename,只取文件名而不要路径
目录名:dirname,只取路径,不要文件名
更改目录
cd [-L|[-P [-e]] [-@]] [dir]
#常用选项
-L #切换至链接目录,默认选项
-P #切换至真实目录,而非链接目录
cd .. #切换至父目录
cd - #切换到上一个目录
cd | cd ~ #切换至当前用户家目录
cd ~username #切换至指定用户家目录
../ #父目录
../../ #父目录的父目录 即向上两层
相关环境变量
$PWD #当前目录
$OLDPWD #上一次目录
[root@ubuntu2204 ~]# echo $PWD $OLDPWD
/root /usr/bin
[root@ubuntu2204 ~]# cd -
/usr/bin
[root@ubuntu2204 bin]# echo $PWD $OLDPWD
/usr/bin /root
列出目录内容
ls [OPTION]... [FILE]...
#常用选项
-a|--all #包含隐藏文件
-l #显示额外的信息
-R|--recursive #目录递归
-d|--directory #仅显示当前目录
-1 #数字1,文件分行显示
-S #按从大到小排序
-t #按mtime排序,时间新的靠前
-u #配合-t选项,显示并按atime从新到旧排序
-U #按目录存放顺序显示
-X #按文件后缀排序
-F|--classify #对不同类型文件显示时附加不同的符号:*/=>@|
说明:
-
ls 查看不同后缀文件时的颜色由 /etc/DIR_COLORS 和@LS_COLORS变量定义
-
ls -l 看到文件的大小,不一定是实际文件真正占用空间的大小
-
ll 是 ls命令的一个别名,在centos 和 ubuntu 系统中,该别名的参数不一样
查看文件状态 stat
一个文件有两部份信息:元数据和具体内容
查看文件元数据
stat [OPTION]... FILE...
#常用选项
-t|--terse #使用简洁格式显示
-f|--file-system #显示相关的文件系统信息,所谓文件系统,对应的就是windows下面的硬盘分区
-c|--format #使用特定格式输出
每个文件有三个时间戳属性
属性 | 说明 | |
---|---|---|
atime | access time | 访问时间,即读取文件内容时间,此字段值会延时更新,以降低IO负载 |
mtime | modify time | 修改内容的时间 |
ctime | change time | 元数据发生变化的时间 |
确定文件内容
文件可以包含多种类型的数据,使用file命令检查文件的类型,然后确定适当的打开命令或应用程序使用
file [options] <filename>...
#常用选项
-b|--brief #只显示结果,不显示文件名
-f|--files-from FILE #从指定文件中获取要处理的文件名
-F|--separator STRING #指定分割符
-L|--dereference #跟随软链接
#示例
#windows的文本格式和Linux的文本格式的区别
[root@ubuntu2204 ~]# cat linux.txt
a
b
c
[root@ubuntu2204 ~]# cat win.txt
a
b
c
[root@ubuntu2204 ~]# file linux.txt win.txt
linux.txt: ASCII text
win.txt: ASCII text, with CRLF line terminators
[root@ubuntu2204 ~]# ll linux.txt win.txt
-rw-r--r-- 1 root root 6 May 8 17:06 linux.txt
-rw-r--r-- 1 root root 9 May 8 17:07 win.txt
文件通配符模式 wildcard pattern
文件通配符可以用来匹配符合条件的多个文件,方便批量管理文件
通配符采用特定的符号,表示特定的含义,此特定符号称为元 meta 字符
常见的通配符如下:
* #匹配零个或多个字符,但不匹配 "." 开头的文件,即隐藏文件
? #匹配任何单个字符,一个汉字也算一个字符,
~ #当前用户家目录
. #当前工作目录
~+ #当前工作目录
~- #前一个工作目录
~mage #用户mage家目录
[0-9] #匹配数字范围
[a-z] #一个字母
[A-Z] #一个字母
[wang] #匹配列表中的任何的一个字符
[^wang] #匹配列表中的所有字符以外的字符
[^a-z] #匹配列表中的所有字符以外的字符
#另外还有在Linux系统中预定义的字符类表示
[:digit:] #任意数字,相当于0-9
[:lower:] #任意小写字母,表示 a-z
[:upper:] #任意大写字母,表示 A-Z
[:alpha:] #任意大小写字母
[:alnum:] #任意数字或字母a-zA-Z0-9
[:blank:] #水平空白字符
[:space:] #水平或垂直空白字符
[:punct:] #标点符号
[:print:] #可打印字符
[:cntrl:] #控制(非打印)字符
[:graph:] #图形字符
[:xdigit:] #十六进制字符
#范例: [ ] 和 { }
[root@ubuntu2204 ~]# ll f{1..5}
ls: cannot access 'f1': No such file or directory
ls: cannot access 'f2': No such file or directory
-rw-r--r-- 1 root root 0 May 8 17:14 f3
-rw-r--r-- 1 root root 0 May 8 17:14 f4
-rw-r--r-- 1 root root 0 May 8 17:14 f5
[root@ubuntu2204 ~]# ll f[1-5]
-rw-r--r-- 1 root root 0 May 8 17:14 f3
-rw-r--r-- 1 root root 0 May 8 17:14 f4
-rw-r--r-- 1 root root 0 May 8 17:14 f5
#范例:比较有无*的功能区别
ls * #等同于 ls 列出当前目录内容,不包括 . 和 ..
ls -a * #等同于 ls 列出当前目录内容,不包括 . 和 ..
ls -a #列出当前目录所有内容,包括 . 和 ..
ls .* #列出当前目录和上级目录的内容, .* 包括 .. 也就是上级目录
ls -d .* #只显示当前目录的内容,有预定的别名 l.
创建空文件和刷新时间
touch 命令可以用来创建空文件或刷新文件的时间
touch [OPTION]... FILE...
#常用选项
-a #改变atime,ctime
-m #改变mtime,ctime
-h|--no-dereference #touch链接文件时,默认是操作其指向的目标文件,此选项表示操作链
接文件本身
-r|--reference #使用某个文件的访问时间和修改时间作为当前文件的访问时间和修改时
间
-d|--date #指定修改时间和访问时间,而不是采用当前系统时间
-t [[CC]YY]MMDDhhmm[.ss] # --time=WORD
--time=STRING #指定修改项 access|atime 等同于 -a, modify|mtime 等同于
-m
-c|--no-create #如果文件不存在,不创建
复制文件和目录
利用 cp(copy)命令可以实现文件或目录的复制
cp [OPTION]... [-T] SOURCE DEST
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...
#常用选项
-i|--interactive #如果目标文件己存在,则提示是否覆盖
-n|--no-clobber #如果目标文件己存在,则跳过此文件复制
-R|-r|--recursive #递归复制,可用于目录的复制
-a|--archive #保留所有属性 相当于 dpR 选项组合
-s|--symbolic-link #不复制文件,而是创建链接
-p #同时复制访问时间,修改时间,权限等属性,同 --
preserve=mode,ownership,timestamps
--preserve[=ATTR_LIST] #选择属性,默认为 mode,ownership,timestamps
-u|--update #当源文件比目标文件新时,才执行复制操作
-v|--verbose #显示复制过程
-b #先备份再覆盖
--backup=numbered #目标存在,覆盖前先备份加数字后缀,形式为 filename.~#~ ,可以保留
多个版本
mode #权限
ownership #属主属组
timestamp #时间戳
links #保留链接
xattr #保留自定义属性
context #保留selinux属性
all #所有属性
源\目标 | 不存在 | 存在且为文件 | 存在且为目录 |
---|---|---|---|
一个文件 | 新建DEST,并将SRC中内容填充至DEST中 | 将SRC中的内容覆盖至DEST中,注意数据丢失风险,建议用 -i选项 | 在DEST下新建与原文件同名 的文件,并将SRC中内容填 充至新文件中 |
多个文件 | 提示错误 | 提示错误 | 在DEST下新建与原文件同名 的文件,并将SRC中内容填 充至新文件中 |
目录需要使用-r选项 | 创建指定DEST同名目录,复制SRC目录中所有文件至DEST目录下 | 提示错误 | 在DEST下新建与原目录同名 的目录,并将SRC中内容复 制至新目录中 |
移动和重命名文件
mv 命令可以实现文件或目录的移动和改名
同一分区移动数据,速度很快,数据位置没有变化
不同分区移动数据,速度相对慢,数据位置发生了变化
mv [OPTION]... [-T] SOURCE DEST
mv [OPTION]... SOURCE... DIRECTORY
mv [OPTION]... -t DIRECTORY SOURCE...
#常用选项
-b #如果目标存在,则先备份
-n|--no-clobber #如果目标文件己存在,则跳过此文件移动
-i|--interactive #如果目标文件己存在,则提示是否覆盖
-u|--update #当源文件比目标文件新时,才执行移动操作
-v|--verbose #显示移动过程
删除文件
使用 rm 命令可以删除文件和目录(注意:此命令非常危险,慎重使用,建议使用 mv 代替 rm)
rm [OPTION]... [FILE]...
#常用选项
-i #删除前确认
-f|--force #不确认直接删除
-r|-R|--recursive #递归删除
-d|--dir #删除空目录
--no-preserve-root #强删根目录
目录操作
显示目录树 tree
tree [-acdfghilnpqrstuvxACDFJQNSUX] [-H baseHREF] [-T title ]
#常用选项
-a #显示所有,包括隐藏目录和文件
-d #只显示目录
-f #显示所有内容的完整路径
-F #在执行文件,目录,Socket,符号链接,管道文件,各自加
上"*","/","=","@","|"号
-g #显示文件属组,没找到组名,以gid代替
-u #显示文件属主,没找到用户名,以uid代替
-p #显示内容权限
-s #显示内容大小
-i #不以层级结构显示
-n #不显示颜色
-t #显示时用修改时间排序
-r #以默认显示顺序的反向规则显示,默认以数字,首字母的顺序规则来显示
-o filename #将显示的内容输出到指定文件中
-L n #只显示n层目录
-D #显示内容修改时间
-C #显示色彩
创建目录 mkdir
mkdir [OPTION]... DIRECTORY...
#常用选项
-m|--mode #目录权限属性
-p|--parents #如果要创建的目录父级目录不存在,则一起创建,是递归的意思
-v|--verbose #显示创建过程
删除空目录 rmdir
rmdir只能删除空目录,如果想删除非空目录,可以使用rm -r 命令,递归删除目录树
rmdir [OPTION]... DIRECTORY...
#常用选项
--ignore-fail-on-non-empty #忽略非空错误提示
-p|--parents #连着父目录一起删除
-v|--verbose #显示删除过程
文件元数据和节点表结构
inode 表结构
在Linux系统中,一切皆文件,
每个文件,又分为文件元数据和具体内容两部份,
一个文件元数据和其具体内容数据,在磁盘分区上,是分开存放的。
这种存储文件元数据的区域就叫 inode,中文译作 "索引节点",
每个文件都有一个inode和n(n>=1)个block 数据块,inode 存储文件元数据,数据块存储文件具体内容 数据,
磁盘在格式化时,系统会自动将磁盘分为两个区域,
一个是 inode 区(inode table),用来存放文件的 inode,
另一个是数据区,分成很多个block(块),用来存放文件的具体内容数据,
一个磁盘分区上有多少个inode和多少个block,由系统自行决定,跟文件系统,磁盘分区大小,数据块 大小有关,
一个磁盘分区,能存放多少个文件,由文件大小,磁盘分区大小,inode数量决定,
inode 编号可重复使用,当删除一个文件之后,其inode 编号会被回收,供下次新文件使用,
每一个inode表记录对应的保存了以下信息:
-
inode number(索引节点编号)
-
文件类型
-
权限
-
属主属组
-
链接数
-
文件大小
-
各时间戳
-
指向具体数据块的指针
-
有关文件的其他数据
目录
目录是个特殊文件,目录文件的内容保存了此目录中文件的列表及inode number对应关系
-
文件引用一个是 inode号
-
人是通过文件名来引用一个文件
-
一个目录是目录下的文件名和文件inode号之间的映射
inode 和 目录
cp和inode
cp 命令:
-
分配一个空闲的inode号,在inode表中生成新条目
-
在目录中创建一个目录项,将名称与inode编号关联
-
拷贝数据生成新的文件
rm和inode
rm 命令:
-
链接数递减,从而释放的inode号可以被重用
-
把数据块放在空闲列表中
-
删除目录项 数据实际上不会马上被删除,但当另一个文件使用数据块时将被覆盖
mv和inode
-
如果mv命令的目标和源在相同的文件系统,作为mv 命令
用新的文件名创建对应新的目录项
删除旧目录条目对应的旧的文件名
不影响inode表(除时间戳)或磁盘上的数据位置:没有数据被移动!
-
如果目标和源在一个不同的文件系统, mv 相当于cp 和 rm
inode编号耗尽 & 磁盘打满
#分区越大,可用的节点编号就越多,当前分区有多少个节点编号,就是说能在当前分区上创建多少个文件
#如果当前分区上的节点编号用光,则无法再创建新文件,系统会提示 “No space left on device”
#如果当前分区上的空间用光,同样无法创建新文件,系统同样提示 “No space left on device”
echo test-{1..523977}.txt | xargs touch #创建大量空文件耗尽inode号
cp /dev/zero /tmp/ #创真实大文件把硬盘打满
df -i #查看磁盘分区inode编号使用情况
df -lh #查看磁盘分区使用情况
#如果磁盘分区还有空间,但提示没有足够空间创建文件,这就是因为 inode 编号耗尽的原因
硬(hard)链接
hard link
硬链接的作用是允许一个文件拥有多个有效的路径名,
新增一个文件,指向某个文件的inode,这样,这两个文件就互为硬链接,
也就是多个文件名,都是指向同一个inode,这是硬链接的本质。
硬链接特性
-
创建硬链接会在对应的目录中增加额外的记录项以引用文件
-
对应于同一文件系统上一个物理文件
-
每个文件引用相同的inode号
-
创建时链接数递增
-
删除文件时:rm命令递减计数的链接,文件要存在,至少有一个链接数,当链接数为零时,该文 件被删除
-
不能跨越驱动器或分区
-
不支持对目录创建硬链接
#格式
ln filename linkname
# . 表示当前目录,目录名也表示当前目录,所以是有2次引用
# .. 表示上级目录,上级目录名引用一次,上级目录中的 . 引用一次,子目录中的 .. 引用一次,所是是
3次引用
[root@ubuntu2204 dira]# ll -ai
total 8
395371 drwxr-xr-x 2 root root 4096 May 9 14:34 ./
395370 drwxr-xr-x 3 root root 4096 May 9 14:34 ../
符号 symbolic (或软 soft)链接
symbolic link,也称为符号链接,类似于windows 中的快捷方式,
软链接是建立一个独立的文件,这个文件的指向的是目标的文件名。
软链接特点
-
一个符号链接的内容是它引用文件的名称
-
可以对目录创建软链接
-
可以跨分区的文件实现
-
指向的是另一个文件的路径;其大小为指向的路径字符串的长度;不增加或减少目标文件inode的 引用计数
-
软链接如果使用相对路径,是相对于源文件的路径,而非相对于当前目录
-
删除软链接本身,不会删除源目录内容
-
删除源目录的文件,不会删除链接文件
#格式
ln -s filename linkname
#创建跨目录的软链接时,源文件不能以当前路径为准,要以目标文件的路径为准
#直接绝对路径较为稳妥
#删除软链接
#这样是删除链接指向的目录
[root@ubuntu2204 0509]# rm -rf dir1.link/
#这样是删除链接文件
[root@ubuntu2204 0509]# rm -rf dir1.link
硬链接和软链接区别总结
选项 | 硬链接 | 软连接 |
---|---|---|
本质 | 本质是同一个文件 | 本质不是同一个文件 |
跨设备 | 不支持 | 支持 |
inode | 相同 | 不同 |
链接数 | 创建新的硬链接,链接数会增加,删除硬链接,链接数减少 | 创建或删除,链接数不会发生变化 |
文件夹 | 不支持 | 支持 |
相对路径 | 原始文件相对路径是相对于当前工作目录 | 原始文件相对路径是相对于链接文件的相对路径 |
删除源文件 | 是链接数减一,但链接文件的访问不受影响 | 链接文件无法访问 |
文件类型 | 和源文件相同 | 链接文件,和源文件无关 |
IO 重定向和管道
标准输入和输出
Linux 系统中有三个最基本的IO设备
-
标准输入设备(stdin):对应终端键盘
-
标准输出设备(stdout):对应终端的显示器
-
标准错误输出设备(stderr):对应终端的显示器
在Linux系统中,一切皆文件,所以,这三个设备也是以文件的形式存在于系统中;
程序从标准输入设备中获取数据,再将运行结果和错误信息输出到标准输出设备和标准错误输出设备;
在虚拟终端中,标准输入输出设备都是当前的终端窗口
[root@ubuntu2204 ~]# ll /dev/std*
lrwxrwxrwx 1 root root 15 May 9 14:11 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 May 9 14:11 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 May 9 14:11 /dev/stdout -> /proc/self/fd/1
[root@ubuntu2204 ~]# ll /proc/self/fd/
total 0
lrwx------ 1 root root 64 Jul 12 17:47 0 -> /dev/pts/1
lrwx------ 1 root root 64 Jul 12 17:47 1 -> /dev/pts/1
lrwx------ 1 root root 64 Jul 12 17:47 2 -> /dev/pts/1
[root@ubuntu2204 ~]# tty
/dev/pts/0
I/O重定向 redirect
重定向:redirect
I/O重定向:将默认的输入,输出或错误对应的设备改变,指向新的目标
标准输出和错误重新定向
STDOUT和STDERR默认是使用当前终端,但也可以重定向到指定终端或指定文件
格式
COMMAND OPERATOR FILE|DEVICE
#覆盖操作符,如果文件存在,会被覆盖
> #把STDOUT重定向到文件
1> #同上
2> #把STDERR重定向到文件
&> #把标准输出和错误都重定向
>& #和上面功能一样,建议使用上面方式
#追加操作符,在原有文件的基础上追加内容
>> #追加标准输出重定向至文件
1>> #同上
2>> #追加标准错误重定向至文件
#示例:标准输出至其它终端
[root@ubuntu2204 ~]# tty
/dev/pts/0
[root@ubuntu2204 ~]# cat fstab > /dev/pts/1
[root@ubuntu2204 ~]# ls > /dev/pts/1
#标准错误输出至其它终端
[root@ubuntu2204 ~]# lss 2> /dev/pts/1
[root@ubuntu2204 ~]# cat null 2> /dev/pts/1
#重定向至文件
#标准输出重定向至文件,覆盖
[root@ubuntu2204 ~]# cat fstab > out.log
#标准输出重定向至文件,追加
[root@ubuntu2204 ~]# cat fstab >> out.log
#标准错误输出重定向至文件,覆盖
[root@ubuntu2204 ~]# cat null 2> err.log
#标准错误输出重定向至文件,追加
[root@ubuntu2204 ~]# cat null 2>> err.log
标准输出和错误输出各自定向至不同位置
COMMAND > sucess.out 2> /path/to/error.out
#示例:同时标准输出和标准错误输出
[root@ubuntu2204 ~]# ls fstab null
ls: cannot access 'null': No such file or directory
fstab
[root@ubuntu2204 ~]# ls fstab null > out.log 2> err.log
合并标准输出和错误输出为同一个数据流进行重定
&> #覆盖重定向
&>> #追加重定向
COMMAND > /path/to/file.out 2>&1
COMMAND >> /path/to/file.out 2>&1
#示例:标准输出和标准错误输出重定向至同一个文件
#标准输出重定向至 out.log,标准错误输出重定向至标准输出
[root@ubuntu2204 ~]# ls fstab null > out.log 2>&1
#标准错误输出重定向到 out.log,标准输出重定向至标准错误输出
[root@ubuntu2204 ~]# ls fstab null 2> out.log 1>&2
[root@ubuntu2204 ~]# ls fstab null &> out.log
[root@ubuntu2204 ~]# ls fstab null >& out.log
#注意
#标准错误输出重定向至标准输出之前,要先定义好标准输出的文件
#标准输出重定向至标准错误输出之前,要先定义好标准错误输出的文件
标准输入重定向
tr 命令
用于转换字符、删除字符和压缩重复的字符。它从标准输入读取数据并将结果输出到标准输出
tr [OPTION]... SET1 [SET2]
#常用选项
-c|-C|--complement #用SET2替换SET1中没有包含的字符
-d|--delete #删除SET1中所有的字符,不转换
-s|--squeeze-repeats #压缩SET1中重复的字符,即删除重复的字符
-t|--truncate-set1 #将SET1用SET2替换,SET2中不够的,就不处理
#常用通配符
[:alnum:] #字母和数字
[:alpha:] #字母
[:digit:] #数字
[:lower:] #小写字母
[:upper:] #大写字母
[:space:] #空白字符
[:print:] #可打印字符
[:punct:] #标点符号
[:graph:] #图形字符
[:cntrl:] #控制(非打印)字符
[:xdigit:] #十六进制字符
#示例
[root@ubuntu2204 ~]# tr 123 abc
123123
abcabc
1233333
abccccc
#小写转大写
[root@ubuntu2204 ~]# tr a-z A-Z
123abcd
123ABCD
[root@ubuntu2204 ~]# tr [:lower:] [:upper:]
123abc
123ABC
#非123就替换成x
[root@ubuntu2204 ~]# tr -c 123 x
13579
13xxxx
#非2-5的内容替换成 x
[root@ubuntu2204 ~]# tr -c '2-5' x
123456789
x2345xxxxx
#删除2-5
[root@ubuntu2204 ~]# tr -d '2-5'
1234567
167
#删除大写字母
[root@ubuntu2204 ~]# tr -d [:upper:]
123abcABC456
123abc456
标准输入重定向
标准输入重定向是使用文件来代替键盘的输入,
从文件中读取数据,代替当前终端的输入设备输入的数据,
此处要严格区分命令是否支持标准输入,标准输入和参数是两个概念;
怎么判断命令能使用标准输入重定向?
不跟任何选项参数,直接回车,看是否等待标准输入,如果是,则该命令可以使用标准输入重定向。
#格式
COMMAND 0< FILE
COMMAND < FILE
#示例
[root@ubuntu2204 ~]# cat a.txt
1+2+3+4+5+6+7+8+9+10
#标准输入重定向
[root@ubuntu2204 ~]# bc < a.txt
55
#标准输入输出重定向
[root@ubuntu2204 ~]# bc < a.txt > rs.txt
[root@ubuntu2204 ~]# cat rs.txt
55
#多行执行
[root@ubuntu2204 ~]# seq -s + 10 > a.txt;bc<a.txt>rs.txt
[root@ubuntu2204 ~]# cat rs.txt
55
#等价于 cat a.txt
[root@ubuntu2204 ~]# cat < a.txt
1+2+3+4+5+6+7+8+9+10
#先输入重定向,再输出重定向
[root@ubuntu2204 ~]#cat < a.txt > b.txt
[root@ubuntu2204 ~]#cat b.txt
1+2+3+4+5+6+7+8+9+10
#输入重定向,再将输入内容输出重定向
[root@ubuntu2204 ~]# cat > abc.txt
标准输入多行重定向
使用 "<<终止词" 命令从键盘把多行重导向给STDIN,直到终止词位置之前的所有文本都发送给STDIN, 有时被称为就地文本(here documents),其中终止词可以是任何一个或多个符号,比如:!,@,$, EOF(End Of File),magedu等,其中EOF比较常用
#示例
[root@ubuntu2204 ~]# cat <<EOF
> 123
> 456
> EOF
123
456
#多行覆盖
[root@ubuntu2204 ~]# cat > abc.txt <<EOF
> 123
> 456
> 789
> EOF
[root@ubuntu2204 ~]# cat abc.txt
123
456
789
高级重定向写法
cmd <<< "string"
含义是 here-string ,表示传给给cmd的stdin的内容从这里开始是一个字符串。
#示例:直接字符串
[root@ubuntu2204 ~]# cat <<< "abc"
abc
[root@ubuntu2204 ~]# bc <<< "1+2+3"
6
[root@ubuntu2204 ~]# tr 'a-z' 'A-Z' <<< "welcome to baidu"
WELCOME TO BAIDU
#执行命令作为重定向的输入
[root@ubuntu2204 ~]# bc <<< `echo 1+2+3`
6
[root@ubuntu2204 ~]# bc <<< `seq -s + 3`
6
[root@ubuntu2204 ~]# tr 'a-z' 'A-Z' <<< `hostname`
ROCKY86
cmd1 < <(cmd2)
名称为 Process substitution ,是由两个部分组成
<(cmd2) 表示把cmd2的输出写入一个临时文件, 注意:< 符号 与( 符号之间没有空格
cmd1 < 这是一个标准的stdin重定向
把两个合起来,就是把cmd2的输出stdout传递给cmd1作为输入stdin, 中间通过临时文件做传递
#示例
[root@ubuntu2204 ~]# bc < <(echo 1+2+3)
6
[root@ubuntu2204 ~]# bc < <(seq -s + 3)
6
[root@ubuntu2204 ~]# tr 'a-z' 'A-Z' < <(hostname)
ROCKY86
#查看中间文件
[root@ubuntu2204 ~]# ll <(hostname)
lr-x------ 1 root root 64 Jul 12 23:23 /dev/fd/63 -> 'pipe:[118809]'
管道
管道
管道(pipe):名顾思义,水管,从一端进去,再从另一端出来。
在shell 中,可以将两个或多个命令(程序|进程)连接起来,将前一个命令的输出作为后一个命令的输入, 就像拿水管将两个命令连起来;
使用管道,要求前一个命令必须支持标准输出,后一个命令必须支持标准输入;
功能说明:
-
将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
-
所有命令会在当前shell进程的子shell进程中执行
-
组合多种工具的功能
格式
COMMAND1|COMMAND2|COMMAND3|...
#注意:STDERR默认不能通过管道转发,可利用2>&1 或 |& 实现,格式如下
COMMAND1 2>&1 | COMMAND2
COMMAND1 |& COMMAND2
#示例
[root@ubuntu2204 ~]# echo 1+2+3|bc
6
[root@ubuntu2204 ~]# cat /var/log/syslog | more
[root@ubuntu2204 ~]# ls --help | grep size
[root@ubuntu2204 ~]# echo $PATH | tr ':' '\n
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/root/bin
#多重管道
[root@ubuntu2204 ~]# echo $PATH | tr ':' '\n' | sort
/bin
/root/bin
/sbin
/snap/bin
/usr/bin
/usr/games
/usr/local/bin
/usr/local/games
/usr/local/sbin
/usr/sbin
#多重管道
[root@ubuntu2204 ~]# ifconfig | head -n 2 | tail -n 1 | tr -s ' ' | cut -d" " -
f3
10.0.0.206
#标准输出和标准错误输出同时使用管道
[root@ubuntu2204 ~]# ls fstab null 2>&1 | tr 'a-z' 'A-Z'
LS: CANNOT ACCESS 'NULL': NO SUCH FILE OR DIRECTORY
FSTAB
[root@ubuntu2204 ~]# ls fstab null |& tr 'a-z' 'A-Z'
LS: CANNOT ACCESS 'NULL': NO SUCH FILE OR DIRECTORY
FSTAB
tee 命令
将标准输入复制到每个指定文件,并显示到标准输出
格式
tee [OPTION]... [FILE]...
#常用选项
-a|--append #内容追加到给定的文件而非覆盖
-i|--ignore-interrupts #忽略中断信号
-p #对写入非管道的行为排查错误,其使用的是 warn-nopipe
--output-error[=模式] #设置写入出错时的行为 (warn|warn-nopipe|exit|exitnopipe)
cmd1 | tee [-a ] filename | cmd2
#示例
#接受标准输入,在标准输出上打印,并写文件
[root@ubuntu2204 ~]# tee tee.log
#管道重定向
[root@ubuntu2204 ~]# echo hello | tee tee.log
hello
#tee.log 里面是hello,终端输出是HELLO
[root@ubuntu2204 ~]# echo hello | tee tee.log | tr 'a-z' 'A-Z'
HELLO
#tee.log 和终端输出都是大写
[root@ubuntu2204 ~]# echo hello | tr 'a-z' 'A-Z' | tee tee.log
HELLO
#追加
[root@ubuntu2204 ~]# echo hello | tr 'a-z' 'A-Z' | tee -a tee.log
HELLO
[root@ubuntu2204 ~]# echo {1..100} | tr ' ' + | bc
5050
[root@ubuntu2204 ~]# echo {1..100..2} | tr ' ' + | bc
2500
[root@ubuntu2204 ~]# seq -s + 1 100 | bc
5050
[root@ubuntu2204 ~]# seq -s+ 1 2 100 | bc
2500
[root@ubuntu2204 ~]# cat <<EOF | tee tee.log
> 123
> 456
> EOF
123
456