文件管理与IO重定向

Linux的文件管理(inode),IO重定向

文件管理

文件目录结构

image-20241024112810532

以 . 开头的文件为隐藏文件

蓝色:目录

绿色:可执行文件

红色:压缩文件

浅蓝色:链接文件

灰色:其他文件

目录功能

 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
/boot				# 引导文件:内核文件(vmlinuz),引导加载器(boot loader,grub)
/bin				# 所有用户使用的基本命令
/sbin				# 管理类的基本命令
/lib				# 启动时,程序依赖的共享库文件和内核模块文件(/lib/modules)
/lib64				# x86_64系统上的辅助共享库文件
/etc				# 配置文件
/home/USERNAME		# 普通用户家目录
/root				# 管理员家目录
/media				# 便携式移动设备挂载点
/mnt				# 临时文件系统挂载点
/dev				# 设备文件及特殊文件存储位置, b:块设备;c:字符设备
/opt				# 第三方应用安装位置
/srv				# 系统上运行的服务使用的数据
/tmp				# 临时文件存储
/proc				# 输出内核与进程相关信息的虚拟文件系统
/sys				# 系统硬件设备相关信息的虚拟文件系统
/selinux			# 存储security enhance linux相关安全策略等信息

/usr				# Unix System Resource
/usr/bin			# 保证系统拥有完整功能而提供的应用程序
/usr/sbin			# 保证系统拥有完整功能而提供的应用程序
/usr/lib
/usr/lib64
/usr/include		# C程序头文件
/usr/share			# 结构化独立的数据,如doc,man等

/var				# variable data files,可变数据目录
/var/cache			# 应用程序的缓存数据目录
/var/lib			# 应用程序的状态信息数据
/var/loacl			# 给/usr/local下的应用程序存储可变数据
/var/lock			# 锁文件
/var/log			# 日志目录及文件
/var/opt			# 给/opt下应用程序存储可变数据
/var/run			# 运行中的进行相关的数据,通常用于存储进程pid的文件
/var/spool			# 应用程序数据池
/var/tmp			# 临时数据

image-20241025100210576

文件类型

文件类型 标识符
普通文件 -
目录文件 d directory
链接文件 l link
块设备 b block
字符设备 c character
管道文件 p pipe
套接字文件 s socket

管道文件

用于进程间通信

  1. 单向通讯
  2. 俩类:匿名,命名(mkfifo # first in first out)

套接字文件

用于进程间的通信(网络)

  1. 双向通讯

文件基础命令

1
2
pwd # print working directory
pwd -P #真实路径;可打印软链接的真实路径

基名&目录名

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# basename /etc/apt/apt.conf.d/01autoremove
01autoremove
# dirname /etc/apt/apt.conf.d/01autoremove
/etc/apt/apt.conf.d

# basename http://nginx.org/download/nginx-1.18.0.tar.gz
nginx-1.18.0.tar.gz
# dirname http://nginx.org/download/nginx-1.18.0.tar.gz
http://nginx.org/download

[root@loong etc]# basename -s .conf.d ld.so.conf.d/ # 去除尾部的后缀
ld.so

目录相关

1
2
3
4
5
6
cd -P /bin # 到真实目录
/usr/bin

# 相关环境变量
$PWD        #当前目录
$OLDPWD     #上一次目录

ls

1
2
3
4
5
ls -a		# 显示所有,包含隐藏
ls -l		# 显示额外信息
ls -R		# 递归显示
ls -ld		# 目录的信息
# ll 是 ls的别名

file:文件信息显示

1
2
[root@loong /]# file bin
bin: symbolic link to usr/bin

dos2unix

将win文件格式化为Linux可运行的文件

stat:文件状态

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[root@loong ~]# stat anaconda-ks.cfg 
  File: anaconda-ks.cfg
  Size: 822             Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 201918974   Links: 1
Access: (0600/-rw-------)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:admin_home_t:s0
Access: 2024-10-24 04:56:32.266122542 -0400
Modify: 2024-10-24 04:56:32.266122542 -0400 # 内容最后被修改的时间
Change: 2024-10-24 04:56:32.266122542 -0400 # 元数据被改变的时间,如权限,所有权
 Birth: 2024-10-21 08:00:43.008980116 -0400

文件通配符

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
*			# 匹配任意长度,任意字符,不包括隐藏文件
?			# 匹配单字符
~			# 当前用户家目录
.			# 当前工作目录
~+			# 当前工作目录
-			# 前一个工作目录
~用户名	  # 用户家目录

# []多用于过滤操作
[0-9]			
[a-z]
[A-Z]
[loasd]		# 匹配中一个
[^loasd]	# 非

{1..5}		# 用于批量操作
{a..z}	

[:lower:]
[:upper:]
...

# 使用时在外再加[]

image-20241024174253468

touch:创建空文件和刷新时间

1
2
touch `date +%F_%T`.log
touch $(date -d "1 year" +%F_%T).log

cp:复制文件与目录

-b:备份

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
cp -i			# 如果文件已存在,则提示是否覆盖
cp -n			# 如果文件存在,则跳过
cp -p			# 保留所属人,所属组,时间戳
cp -b			# 先备份在覆盖
cp -a			# 保留软链接,递归复制,保留文件属性

# copy整个目录
cp -r			#使用-r,否则报错
# -b 建议使用

cp --backup=numbered filea.txt fileb.txt
x.log  y.log  y.log.~1~  y.log.~2~

mv:移动;rename重命名文件

-b:备份

1
2
3
4
mv -b			# 移动前先备份
mv -i			# 提示覆盖
mv -n			# 文件存在,跳过
mv -u			# 只有源文件比目标文件新时,才执行

rename

1
2
3
4
5
6
7
rename -s		# 如果目标是链接文件,则重命名其指向
rename -o		# 不覆盖已存在的文件

rename 更改前内容 更改后内容 指定文件

# 批量更改
rename  txt log *.txt

ubuntu的rename,使用方法不一样。

1
2
rename 's/txt/html/g' f*	# 后缀更改
rename 's/$/.bak/' *		# 后缀添加

rm 删除文件

1
2
3
4
5
6
7
8
9
rm -i			# 删除前确认
rm -f			# 不确认,直接删除
rm -r			# 递归删除,不递归删除不了文件夹与它下面的文件
rm -d			# 删除空目录

# 删除一些带特殊符号的文件,如 -f,'~'
rm -f ./-f
rm -f ./'~'
# 指定目录

定义别名避免误删,将文件移动到/tmp中

1
alias rm ='mv -t /tmp'

tree 树形展示结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
-a			# 所有
-d			# 只目录
-f			# 完整路径
-F			# 区分文件类型
-u			# 显示所属人
-g			# 显示所属组
-p			# 显示权限
-s			# size
-t			# time, 时间排序
-o file		# 输入到文件中
-L n		# 显示多少层
-D			# 显示修改时间
-C			# 显示颜色

mkdir 创建目录

1
2
mkdir -m=777	# 设置权限
mkdir -p		# 无父目录时,一起创建

rmdir 删除目录

1
rmdir -p		# 连父目录一起删除

文件元数据与节点表结构

inode表结构

元数据与内容数据分开存放。

每个文件都有一个inode和n个block数据块;inode存元数据,数据库存内容数据。

  • inode number
  • 文件类型
  • 所属人所属组
  • 链接数:多少文件名指向这个inode
  • 文件大小
  • 各种时间戳
  • 指向数据块的指针
  • 其他数据

目录

是特殊的文件

存储目录下文件名与其inode的映射

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
df -Th		# T:type;h:human

[root@loong ~]# df -i
Filesystem                  Inodes IUsed   IFree IUse% Mounted on
/dev/mapper/openeuler-root 4587520 60955 4526565    2% /
devtmpfs                    427014   416  426598    1% /dev
tmpfs                       431725     1  431724    1% /dev/shm
tmpfs                         1024    18    1006    2% /sys/fs/cgroup
tmpfs                       819200   811  818389    1% /run
tmpfs                      1048576    11 1048565    1% /tmp
/dev/sda2                    65536   384   65152    1% /boot
/dev/mapper/openeuler-home 8200192    11 8200181    1% /home
# Inodes是此文件系统inode总量

硬链接

一个inode,有多个文件指向该inode

  • inode链接数递增
  • 不能跨驱动器或分区
  • 不支持对目录创建硬链接
1
ln filename linkname

软链接

符号链接,快捷方式

  • 可对目录软链接
  • 可跨分区
  • 软链接文件的数据块是链接的路径名
1
ln -s filename linkname

全使用绝对路径

删除软链接

1
2
3
rm -rf a.link		#删除链接文件

rm -rf a.linl/		# 删除链接文件指向目录下文件

inode编号耗尽,磁盘打满

大量空文件会把inode编号占满

大文件会把磁盘占满,inode编号仍有剩余

删除大文件操作

将/dev/null覆盖大文件

1
cat /dev/null > /var/log/huge.log

/dev/null会丢弃写入的一切东西,输出一个EOF。(黑洞)

提示空间满 No space left on device,但 df 可以看 到空间很多,为什么?

  1. df为磁盘空间,可能是inode分配完了,使用df -i查看inode数量
  2. 被分配的磁盘创建满,被管理员限制,quota
  3. 剩下可能为必要的运行空间

提示空间快满,使用 rm 删除了很大的无用文件后,df 仍然看到空间不足,为什么?如何解决?

  1. 文件名被删除,但文件资源仍然被某些进程持有,导致磁盘空间无法释放
  • lsof (list open file)

    • 查看进程打开的文件信息
  • 终止进程

  • 清空文件的内容,而不是文件

  • 重启服务或系统

IO

重定向

覆盖式重定向

1
2
>		# 左 重定向到 右
<		# 右 重定向到 左;多行文件处理

追加式重定向

1
2
>>		# 追加到文件末尾
<<		# 多行文件处理

管道

1
2
|		# 管道符,命令间传递消息;左到右
ps aux | grep a

后台执行

1
2
&
sleep 5 &

信息符号

1
2
3
4
5
6
7
8
9
标准输入 0
标准输出 1
标准错误 2

bash a.sh 2> err.log		# 2与>间无空格

2>&1		# 标准错误重定向至标准输出
1>&2		# 标准输出重定向至标准错误
>&			# 标准输入与标准错误都重定向

临时shell

1
2
(命令; 命令)		# 临时子shell,操作完后无残留
{ 命令; 命令 }		# 临时shell,保留操作结果,前后要有空格

标准输入重定向

使用文件来代替键盘输入

1
cat < a.txt > b.txt		# 将a.txt输入给cat,再将cat输出的内容输入给b.txt

<<EOP: 标准输入多行重定向

<<-EOP用于脚本中,忽略EOP前的制表符

可进行多行标准输入

EOP标志结束

1
cat > c.txt <<EOP

tee

将标准输入复制到每个指定文件夹,并显示到标准输出

搭配<<EOP使用,EOP会成为结束标志

-a 追加

tee filename

之后会让你输入,边输入边回显

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[root@loong ~]# tee tee.log <<EOP
> sdqw
> sadq
> cawrqw
> 
> 
> safwqw
> EOP
sdqw
sadq
cawrqw


safwqw

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf

在当前用户解析输入内容

之后再由root去写入文件

  • 系统文件通常有root用户写入,避免权限问题

read,让用户输入,对脚本内参数赋值

-s 不显示用户输入

-n 限制字符数量

-t 输入时长

-p “输入passwd” 输入提示

<<< 高级重定向

<:是文件输入重定向,后面的会被解析成文件文件

<<<:是字符串重定向