程序员在旅途

用这生命中的每一秒,给自己一个不后悔的未来!

0%

Linux文件操作命令总结

一、综述

在Linux系统功能设计中,文件系统承担着整个系统的数据持久化功能,而文件又是文件系统的数据处理单元,管道、socket、块设备、文件目录等均可以通过文件的方式来进行管理,熟练的掌握文件操作至关重要。
本篇文章从以下几个方面总结常用的文件操作命令,致力于提高Linux运维效率。

  • 磁盘信息概览
  • 文件摘要查看命令
  • 文件查找命令
  • 文件压缩与解压命令
  • 文件传输命令

二、磁盘信息概览

在Linux中,磁盘作为存储数据的主要载体,了解当前系统中磁盘的分区状态、挂载的文件系统、空间使用情况等数据能够让我们对存储状态有一个更加全面的掌握。主要会涉及到lsblkdfdu等命令,可以通过 man lsblk 或者 lsblk -h 查看详细的使用方式。

2.1 lsblk

lsblk 通过读取sysfs虚拟文件系统来收集系统中所有的可用或者指定的块设备信息(sysfs是一种对系统设备进行管理的虚拟文件系统)。

1
2
3
4
5
6
7
[root@docker-registry ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 34G 0 disk
├─sda1 8:1 0 300M 0 part /boot
├─sda2 8:2 0 2G 0 part [SWAP]
└─sda3 8:3 0 31.7G 0 part /
sr0 11:0 1 1024M 0 rom

sd代表采用scsi、sata接口上的设备,sda代表第一个设备,依次编号,如sdb、sdc等,sda1、sda2、sda3是sda的3个分区;
MOUNTPOINT 是挂载点,即在系统中的挂载位置;
SIZE 是空间大小;
TYPE 是类型,有disk、part(分区)、rom等。

可以加上 -f 可以查看采用的文件系统:

1
2
3
4
5
6
7
[root@docker-registry ~]# lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT
sda
├─sda1 xfs e86e8ead-d69d-4e62-92ae-5def7de95cd5 /boot
├─sda2 swap 7079459f-7493-4e84-b870-dfbc921928e3 [SWAP]
└─sda3 xfs 73d4f659-9967-4a9c-abf2-5784f236c68e /
sr0

2.2 df

df 用于查看 文件系统中磁盘空间的使用情况,df命令使用statfs这个系统调用,直接读取分区的超级块信息获取分区使用情况,它的数据基于分区元数据,只能针对整个分区。

1
2
3
4
5
6
7
8
9
10
11
12
[root@docker-registry ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 1.4G 0 1.4G 0% /dev
tmpfs 1.4G 0 1.4G 0% /dev/shm
tmpfs 1.4G 12M 1.4G 1% /run
tmpfs 1.4G 0 1.4G 0% /sys/fs/cgroup
/dev/sda3 32G 20G 13G 61% /
/dev/sda1 297M 166M 132M 56% /boot
overlay 32G 20G 13G 61% /var/lib/docker/overlay2/8e5c1831a1fdf28d8d53f0ba7e417331e78c3af85f2205f24c749503f311680b/merged
overlay 32G 20G 13G 61% /var/lib/docker/overlay2/2f48f6274de0ce36fb3d62e260e9c0e20061ea27711a23713c71eff03461016d/merged
shm 64M 0 64M 0% /var/lib/docker/containers/82456489bf8d4f250f654a84c87ef465da0ee0e8c54bd57a3b8c82ba7184864a/shm
tmpfs 280M 0 280M 0% /run/user/0

2.3 du

du 用于查看目录或文件的大小,对统计文件逐个调用fstat这个系统调用,获取文件大小,它的数据基于文件获取,可以跨多个分区操作。

以查看 /root 目录下的空间占用大小为例,-d 指明深度为1(加上 -d 很重要,默认会列出所有文件目录,会很多),-h 以友好的方式展示出来,sort -rn排序:

1
2
3
4
5
6
7
8
9
10
11
12
[root@docker-registry ~]# du /root -d 1 -h | sort -rn 
781M /root/.cache
4.0K /root/.config
4.0K /root/.ssh
0 /root/.pki
4.7G /root/go
40M /root/docker
721M /root/.vscode-server
674M /root/test
196K /root/logs
196M /root/etcd
7.1G /root

仅显示指定目录或文件的总磁盘使用情况

1
2
[root@docker-registry ~]# du -sh /root 
239M /root

#dfdu 结果不一致的排查思路

1.首先要明确,du 用于查看目录或文件的大小,df 用于查看 文件系统中磁盘空间的使用情况,当文件被删除,在文件系统的目录中不存在时,du就不会统计到这个文件,如果此时运行的进程持有这个已经被删除的文件句柄,那么这个文件就不会真正在磁盘中被删除,分区超级块中的信息也就不会更改,df仍会统计这个被删除的文件。所以就有可能造成df看到的大小比du要大。
可以使用lsof命令查找运行中的进程占用已经删除的文件,找到异常进程后kill即可。

1
lsof | grep delete |sort -nrk 7|head

2.其次,文件在存储到磁盘中的时候,会同时用到inode和block,inode保存文件属性信息,包括文件名,大小,权限,时间,存储位置等,而block中则保存实际的数据,df默认统计是没有inode信息的,如果inode用完的话,即使磁盘还有空间也无法创建新文件了。发生这种情况的原因一般是系统中小文件过多,占用了大量的inode节点,找到对应目录,删除一些文件就可以了,可以使用以下命令看下node的情况:

1
df -ih

0字节的文件也会杂用inode,如下命令可删除:

1
find /home -type f -size 0 -exec rm {}\;

目录下有大量小文件也会导致inode增加:

1
for i in /var/spool.. do echo $i; find $i wc -l; done

3.也有可能是du没有统计到隐藏文件,或者文件系统损坏导致,这种情况就得要具体来分析查看了,查看隐藏文件可使用如下命令:

1
du -sh .[!.]*

三、文件摘要查看命令

3.1 file

file 用于查看文件类型

1
2
3
4
5
6
7
8
[root@docker-registry ~]# file dive_0.9.2_linux_amd64.rpm
dive_0.9.2_linux_amd64.rpm: RPM v3.0 bin i386/x86_64 dive-0.9.2-1
[root@docker-registry ~]# file coredns.tar
coredns.tar: POSIX tar archive
[root@docker-registry ~]# file go/
go/: directory
[root@docker-registry ~]# file anaconda-ks.cfg
anaconda-ks.cfg: ASCII text

3.2 stat

stat 命令用于查看文件状态

1
2
3
4
5
6
7
8
9
10
[root@docker-registry ~]# stat anaconda-ks.cfg
File: ‘anaconda-ks.cfg’
Size: 2808 Blocks: 8 IO Block: 4096 regular file
Device: 803h/2051d Inode: 33574980 Links: 1
Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root)
Context: system_u:object_r:admin_home_t:s0
Access: 2022-05-21 22:18:29.982417766 -0700
Modify: 2021-12-05 02:30:10.862007656 -0800
Change: 2021-12-05 02:30:10.862007656 -0800
Birth: -

3.3 type

type 用于查看命令的类型,命令一般主要有以下类型:

alias:别名;
keyword:关键字;
builtin:内置命令;
file:外部命令。

常见的参数有:

-t 输出类型名,如file
-p 如果是外部命令,则显示其所在路径
-a 对于外部命令,它会显示命令路径,命令类型等信息

1
2
3
4
5
6
7
8
9
[root@docker-registry ~]# type ls
ls is aliased to `ls --color=auto'
[root@docker-registry ~]# type -a ls
ls is aliased to `ls --color=auto'
ls is /usr/bin/ls
[root@docker-registry ~]# type -t ls
alias
[root@docker-registry ~]# type -t type
builtin

3.4 md5sum

md5sum 查看文件或者字符串的MD5值,用于校验文件的一致性,判断是否被篡改。

1
2
3
4
[root@docker-registry ~]# md5sum --help
Usage: md5sum [OPTION]... [FILE]...
Print or check MD5 (128-bit) checksums.
With no FILE, or when FILE is -, read standard input.

#查看文件的md5值

1
2
[root@docker-registry ~]# md5sum anaconda-ks.cfg
dde780f07afcef3b5966aac90a2e558b anaconda-ks.cfg

#查看字符串的md5值

1
2
3
4
[root@docker-registry ~]# echo -n "md5sum-check-test"| md5sum
a5985eb6cbfea030806722021bf31e09 -
[root@docker-registry ~]# echo -n "md5sum-check-test"|md5sum |cut -d" " -f1
a5985eb6cbfea030806722021bf31e09

md5sum: 显示或检查 MD5(128-bit) 校验和,此处校验字符串时输出内容包含两个域,有一个是”-“,表示从标准输入读取。
echo -n : 对输出的字符串不打印换行(echo -n 后面的-n参数必须加上, 这样算出的字符串的md5值才正确)
cut: cut用来从标准输入或文本文件中剪切列或域。-d 指定与空格和tab键不同的域分隔符,-f1 表示选择第一个域。

四、文件查找命令

该命令提供在Linux中按照给定的条件查找文件能力,并通过管道和其他命令结合,实现对文件的进一步操作。

4.1 find

find命令用于在指定的目录查找文件

1
2
3
4
[root@docker-registry ~]# find --help
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
default path is the current directory; default expression is -print
expression may consist of: operators, options, tests, and actions

其中[-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec]参数不常用,更一般的形式为:

1
find  [path...] [expression]

path:查找路径;
expression:包含“-options [-print -exec -ok …]”,-options 筛选参数,-print输出格式,-exec/-ok提供对查找结果作进一步处理;-exec 的使用格式为-exec command {} \;,command是相关的指令,比如 ls -l

其中 options 有以下常见选项:

-name 匹配名称
-perm 匹配权限
-user 匹配所有者
-group 匹配所有组
-mtime -n +n 匹配修改内容的时间
-atime -n +n 匹配访问内容的时间
-size 匹配文件大小
-prune 忽略某个目录
–type b/s/c/p/l/f 匹配文件类型 块设备 目录 字符设备 管道 链接文件 文本文件

#匹配查找

查找当前目录下满足以下条件的文件:大小size < 1k(-n 小于n k,+n 大于 n k),文件名称name 满足后缀为 *.txt,文件类型为f(f 文件,d 目录),user 为 root,group为 root,,修改时间mtime 1天以内(+n n天以前,-n n天以内),创建时间在ctime 1天以内,文件权限为 755:

1
[root@docker-registry ~]# find ./ -size -1 -name "*.txt" -type f -user root -group root -mtime -1 -ctime -1  -perm 755

#对查找到的文件进一步处理

查找当前目录 名称为 user.txt 并拷贝到该目录下 ./find-test/user-cp.txt:

1
[root@docker-registry ~]# find ./ -name user.txt -exec cp {} ./find-test/user-cp.txt \;

查找./find-test/user-cp.txt 并删除:

1
[root@docker-registry ~]# find ./ -name user-cp.txt -exec rm -rf  {} \;

4.2 which/whereis

which/whereis 用于查找二进制文件位置,其中 which 用于在 PATH目录下查找程序可执行文件的路径,如果未添加在PATH中,则不会被搜索到。whereis命令是从文件索引数据库中查找查找程序的二进制、源文件、man文件,查找比which更广泛。

1
2
3
4
[root@docker-registry ~]# which go
/usr/local/go/bin/go
[root@docker-registry ~]# whereis go
go: /usr/local/go /usr/local/go/bin/go

五、文件压缩与解压命令

在linux中,文件打包、压缩、解压缩是比较常见的几个操作,处理后的文件可以便于做传输等操作。
打包和压缩是两个不同的概念,打包是将一些文件或目录变成一个总的文件,压缩则是将一个大文件通过压缩算法变成一个小文件。
常见的几个处理命令有:tar 、gzip 、 zip 、unzip等

5.1 tar

tar是Tape ARchive 的缩写,一种类UNIX系统上常用的归档打包工具,可用于把文件名、访问权限、文件内容等信息打包到一起,可以操作的对象是目录和文件,使用 tar 打出来的包称为 tar 包,也可以加入压缩参数同时对打包后的文件进行压缩。
tar 常用的参数如下:

tar 用于打包压缩或者解开打包文件
-c 创建打包文件
-x 解开打包文件
-z 用Gzip压缩或者解压
-j 用bzip2压缩或者解压
-v 显示解压或者压缩过程
-f 目标文件名
-p 保留原始的全新啊或者属性
-P使用绝对路径来压缩
-C 指定解压目录

# tar打包解包

./find-test/ 打包成 tar 包

1
2
3
4
5
[root@docker-registry ~]# tar -cvf ./find-test/user.txt.tar ./find-test/
./find-test/
./find-test/user.txt
./find-test/user-cp.txt
tar: ./find-test/user.txt.tar: file is the archive; not dumped

./find-test/user.txt.tar 解压缩到 ./find-test/tar目录下

1
2
3
4
[root@docker-registry ~]# tar -xvf ./find-test/user.txt.tar -C ./find-test/tar
./find-test/
./find-test/user.txt
./find-test/user-cp.txt

# tar压缩解压缩

./find-test/ 打包成 tar 包并压缩成.gz包

1
2
3
4
5
6
7
8
9
10
11
[root@docker-registry ~]# tar -czvf ./find-test/user.txt.tar.gz ./find-test/
./find-test/
./find-test/user.txt
./find-test/user-cp.txt
./find-test/user.txt.tar
./find-test/tar/
./find-test/tar/find-test/
./find-test/tar/find-test/user.txt
./find-test/tar/find-test/user-cp.txt
./find-test/user.txt.tar.gz
tar: ./find-test: file changed as we read it

./find-test/user.txt.tar.gz 解压缩到 ./find-test/gz目录下

1
[root@docker-registry ~]# tar -xzvf./find-test/user.txt.tar.gz -C ./find-test/gz

5.2 zip/unzip压缩解压缩

linux 下也提供了 zip 和 unzip 程序,zip 是压缩程序,unzip 是解压程序。
zip 压缩文件, 将 find-test/ 下的文件压缩为 user.txt.zip:

1
[root@docker-registry ~]#  zip user.txt.zip find-test/

unzip 压缩文件, 将 fuser.txt.zip 解压到 find-test/gz/ 目录:

1
[root@docker-registry ~]#  unzip user.txt.zip -d find-test/gz/

六、文件传输命令

linux中可以通过scp命令实现跨主机的文件传输能力,从而实现文件在不同的主机之间快速流转。

6.1 scp 文件传输

scpsecure copy (remote file copy program)的缩写,用于快速的实现主机之间的安全文件传输,一般采用的22端口。
主要用法为:

scp <origin-path> <target-path>

#从服务器复制文件(夹)到本地

1
2
[root@docker-registry ~]#  scp -r root@192.168.1.100:/data/  find-test/   # -r 文件夹
[root@docker-registry ~]# scp root@192.168.1.100:/data/test.tar find-test/

#从本地上传服务器

1
2
[root@docker-registry ~]#  scp -r find-test/  root@192.168.1.100:/data/     # -r 文件夹
[root@docker-registry ~]# scp find-test/user.txt root@192.168.1.100:/data/

6.2 wget 文件下载

wget是一个在Linux命令行下必不可少的文件下载工具,wget支持HTTP,HTTPS和FTP协议,可以使用HTTP代理;wget在下载过程中,会显示进度条、文件大小、下载速度等.

wget 的命令行格式为:

1
wget [OPTION]... [URL]...

常见参数如下:

-O 以其他名称保存下载的文件;
-P 选项将文件下载到指定目录;
-c 选项断点续传;
-b 选项在后台下载;
-i 选项下载多个文件;
–limit-rate 选项限制下载速度;
–tries 选项增加重试次数(默认重试20次)。

下载redis到/root目录下并重命名,限制速率和重试次数:

1
wget -O redis-6-latest.tar.gz -P /root --limit-rate=1m --tries=50 https://download.redis.io/releases/redis-6.0.8.tar.gz

6.3 nc+tar 实现两台主机之间文件传输

nc (netcat) 是一个可以监听或和任意 tcp/udp 端口建立连接的工具,也可以与tar一起用于主机之间的文件传输。
先在接收文件的主机启动nc监听,等待文件流的到来:

1
2
3
nc -l port >file
nc -l -p 9995 >zabbix.rpm
nc -l -p 9999 | tar xf -

然后在发送端发送文件

1
2
nc SERVER-IP 9995 < zabbix-release-2.4-1.el6.noarch.rpm
tar cf - find-test/ | nc SERVER-IP 9999

短划线 - 在这两个 tar 命令中的作用是将数据从标准输出传递到标准输入,以便通过管道将数据从一个 tar 命令传输到另一个 tar 命令,从而实现文件的复制和解压缩操作。这是一种常见的用法,用于在不创建临时文件的情况下在命令之间传递数据。

七、总结

以上便是对Linux中文件基础操作命令的总结,文件操作不仅如此,此处备忘;更深入的文件理解还需要慢慢地领悟,以便更深入的去了解 linux设计中的 一切皆文件 的思想。