Skip to content

文件管理

目录结构

和 Windows 不一样,Linux是以树的结构来管理文件系统的。我们将树的根结点称为根目录,用 / 表示。

在Linux中,我们是以分门别类的方式来管理文件的,也就是说,我们会将功能相似的文件放到同一个目录下进行管理。这和Windows按工程组织文件的方式不太一样。

主要目录介绍

  • /bin: binary,二进制文件,可执行程序,shell命令。如: lsrmmvcp 等常用命令。
  • /sbin: s是Super User的意思,这里存放的是系统管理员使用的系统管理程序。 如:ifconfighaltshutdownreboot 等系统命令
  • /dev: device 设备文件,在linux下一切皆文件
    • 硬盘,显卡,显示器
    • 字符设备文件、块设备文件。如: 在input目录下执行: sudo cat mouse0,移动鼠标会显示有输入.
  • /lib: linux运行的时候需要加载的一些动态库。如: libc.solibpthread.so
  • /mnt: 手动的挂载目录,如U盘等
  • /media: 外设的自动挂载目录,如光驱等。
  • /root: linux的超级用户root的家目录
  • /usr: unix system resource——类似于WINDOWS的programe files目录
    • include目录里存放头文件,如: stdio.hstdlib.hstring.hpthread.h
    • games目录下的小游戏-如: sl小火车游戏
  • /etc: 存放配置文件
    • /etc/passwd man 5 passwd 可以查看passwd文件的格式信息
    • /etc/group man 5 group 可以查看group文件的格式信息
    • /etc/profile 系统的配置文件,修改该文件会影响这个系统下面的所有的用户
  • /opt: 安装第三方应用程序。比如安装oracle数据库可以在这个目录下
  • /home: linux操作系统所有用户的家目录。宿主目录或者主目录,如: /home/itcast
  • /tmp: 存放临时文件。新建在这个目录下的文件会在系统重启后自动清除

相对路径和绝对路径

绝对路径

从根目录开始表示的路径,也就是从/开始,例如:/home/itcast

相对路径

从当前所处的目录开始表示的路径。

  • . 表示当前目录
  • .. 表示当前目录的上一级目录

文件和目录操作

查看当前工作目录

pwd(print working directory) 命令可以查看当前工作目录

shell
$ pwd
/home/he

改变当前工作目录

cd(change directory) 命令可以改变工作目录

shell
$ man cd
  cd change the working directory
格式:
  cd [选项] [directory]

常用方式:

shell
$ cd # 切换到用户家目录
$ cd /usr/lib # 切换到/usr/lib目录
$ cd / # 切换到 / 目录
$ cd ~ # 切换到用户家目录
$ cd . # 切换到当前工作目录(不切换)
$ cd .. # 切换到父目录
$ cd - # 切换到上一次目录

注意

上一次目录保存在环境变量OLDPWD中(可以通过env命令查看),它不是用栈结构管理的。

创建目录

我们可以用 mkdir 命令来创建目录

shell
$ man mkdir
  mkdir - make directories
格式:
  mkdir [选项] directory...
常用选项:
  -p, --parents
    如果父目录不存在,则创建父目录

常用方式:

shell
$ mkdir dir
$ mkdir dir1 dir2 dir3
$ mkdir -p a/b/c

删除空目录

rmdir 只能用来删除空目录

shell
$ man rmdir
  rmdir - remove empty directories
格式:
  rmdir [选项] dirctory...
常用选项:
    -p, --parents
      递归删除空目录

常用方式:

shell
$ rmdir dir
$ rmdir dir1 dir2 dir3
$ rmdir -p a/b/c

通配符

通配符(wildcard character),可以用于匹配单个或多个字符。其中:

shell
*: 匹配任意多个字符(包括0个)
?: 匹配任意一个字符

集合(类):  
  [characters]匹配集合内任意一个字符。
  [!characters]匹配集合外任意一个字符。
  比如:[abc], [!abc], [0-9], [a-z], [0-9A-Za-z_]等

rmdir 命令可以和通配符一起使用 (通配符可以提升命令的威力):

shell
$ rmdir dir?
$ rmdir dir*
$ rmdir [!abc]

查看目录内容

ls(list) 命令可以查看目录内容:

shell
$ man ls
  ls - list directory contents
格式:
  ls [选项] [FILE]...
常用选项:
    -a, --all
      显示所有的内容,包括以.开头的文件和目录
    -i, --inode
      显示文件的inode编号(inode是物理文件的标识)。
    -l
      以长格式的形式显示目录中的内容
    -h, --human-readable
      和-l选项一起使用,以人类可读的方式显示文件的大小。

常用方式:

shell
$ ls # 查看当前工作目录
$ ls dir # 查看dir
$ ls dir1 dir2 dir3 # 查看dir1,dir2,dir3
$ ls -a dir # 查看dir中的所有内容,包括以.开头的文件和目录
$ ls -ilh dir # 显示inode编号,显示详细信息,并以人类可读的方式显示文件的大小

接下来,我们一起来看一下目录项的详细信息:

shell
$ ls -l
总用量 8560
-rw-rw-r-- 1 he he 4349666 3月 7 11:12 a.txt
drwxrwxr-x 2 he he 4096 3月 2 21:18 c
...
字段含义
文件类型第一列的第一个字母表示文件类型
权限文件的权限,rwxrwxrwx表示可读可写可执行
链接数文件的链接数(硬链接数),表示文件被多少个进程打开
用户名文件的拥有者
组名文件所属组
文件大小文件的大小,以字节为单位
日期文件的修改时间
文件名文件名

第1列的第一个字母用来表示文件的类型。

字符文件类型
-普通文件
d(directory)目录
l(symbolic link)符号链接
b(block)块设备文件(磁盘)
c(character)字符设备文件件(鼠标,键盘,显示器...)
p(named pipe)有名管道
s(socket)本地套接字

第1列后面九个字符(分为3组)表示权限。 依次代表拥有者、拥有组和其他用户的读、写、执行权限。可读则显示r,可写则显 示w,可执行则显示x, 没有相关权限则显示-。

以树状结构显示目录内容

tree 命令不是Linux系统自带的命令,使用之前,我们必须先安装 tree 命令:

shell
$ sudo apt install tree

tree 命令可以以树状结构显示目录内容:

shell
$ man tree
  tree - list contents of directories in a tree-like format.
格式:
  tree [选项] [directory]...

常用方式:

shell
$ tree # 以树状结构显示当前工作目录的内容
$ tree dir # 以树状结构显示目录dir中的内容
$ tree dir1 dir2 dir3 # 以树状结构显示目录dir1, dir2, dir3中的内容

复制文件或目录

cp(copy) 命令可以用来复制文件和目录。

shell
$ man cp
  cp - copy files and directories
格式:
    cp [选项] SOURCE DEST
    cp [选项] SOURCE... DEST
常用选项:
    -n, --no-clobber
      如果文件已存在,则不覆盖(默认会覆盖已有文件)。
    -i, --interactive
      如果文件存在,则给用户提示信息(由用户决定是否覆盖?)
    -R, -r, --recursive
      递归复制(用于copy目录)

常用方式:

shell
$ cp text1 text2 # 将text1复制到text2中;如果text2存在,则覆盖。
$ cp text1 text2 text3 dir # 将text1,text2,text3复制到目录dir中;如果文件已存在,则覆盖。
$ cp -n text1 text2 # 将text1复制到text2中;如果text2存在,不覆盖。
$ cp -i text1 text2 text3 dir # 将text1,text2,text3复制到目录dir中;如果文件已存在,则提示用户是否覆盖。
$ cp -r dir1 dir2 # 递归地将目录dir1复制到目录dir2

挂载NFS共享文件夹

在客户端挂载共享目录,您需要安装NFS客户端软件:

shell
# 适用于Debian系
sudo apt install nfs-common -y

# 适用于Centos
sudo yum install nfs-utils -y

然后,创建一个挂载点并挂载NFS共享:

shell
mkdir -p ~/nas/files
# sudo mount server_ip:远程共享的路径 挂载到本机的路径
sudo mount 192.168.31.3:/volume1/files ~/nas/files

在这里,server_ip是NFS服务器的IP地址。

验证挂载

df -h

应该可以看到以ip地址开头的文件夹已经被挂载

权限问题

通过群晖共享的NFS在使用上方命令挂载以后存在普通用户无法访问的问题,通过设置文件权限来解决

shell
sudo chmod 775 -R ~/nas/files

最简单的解决办法,就是在群辉中设置权限为 映射所有用户为 admin,但是这种方法相对来说并不安全。

设置客户端自动挂载

要使共享在启动时自动挂载,您可以将以下行添加到 /etc/fstab 文件中:

shell
# server_ip:远程共享的路径 挂载到本机的路径 nfs defaults 0 0
192.168.31.3:/volume1/files /home/zm/nas/files nfs defaults 0 0

参考文献

文心一言关于权限问题的解答

Q: 使用sudo命令挂载后普通用户无权限访问,只有root用户才有权限访问

在Linux系统中,使用sudo命令挂载NFS共享后,如果挂载点(如/mnt/nfs)的权限没有正确设置,那么普通用户可能无法访问该挂载点。默认情况下,挂载点的权限可能只允许root用户访问。

要解决这个问题,你可以通过更改挂载点的权限来允许普通用户访问。你可以使用chmodchown命令来修改挂载点的权限和所有权。

但是,请注意,直接修改挂载点的权限可能不是最佳做法,特别是当NFS服务器上的共享目录的权限和所有权与客户端不同时。更好的做法是在NFS服务器上设置正确的共享权限,并确保这些权限在客户端上得到尊重。

不过,如果你只是想快速测试或临时允许普通用户访问,你可以使用以下命令:

bash
# 更改挂载点的所有权(假设你想让用户名为username的用户能够访问)
sudo chown -R username:username /mnt/nfs

# 或者,如果你不想更改所有权,但想允许所有用户读取和进入该目录
# 注意:这可能会带来安全风险,因为任何用户都可以写入和删除文件
sudo chmod -R 755 /mnt/nfs
# 或者,如果你还想允许执行文件(通常不需要)
# sudo chmod -R 775 /mnt/nfs

# 更安全的做法是仅允许读取和执行(如果适用)
sudo chmod -R 750 /mnt/nfs
# 然后将用户添加到某个组,并将该组的用户添加到挂载点的组所有权中
# sudo groupadd nfsgroup
# sudo usermod -aG nfsgroup username
# sudo chgrp nfsgroup /mnt/nfs
# sudo chmod -R 770 /mnt/nfs

但是,请记住,这些更改只会在客户端上生效,并且如果NFS服务器上的共享权限更严格,那么这些更改可能会被忽略。

最佳实践是在NFS服务器上设置正确的共享选项,例如:

bash
# 在NFS服务器的/etc/exports文件中添加或修改行
/path/to/shared /192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)

注意no_root_squash选项,它允许root用户以root身份访问NFS共享(这通常不是推荐的做法,因为它可能会带来安全风险)。如果你想要避免这种情况,并希望所有用户(包括root)都以普通用户身份访问NFS共享,那么你应该省略no_root_squash选项。

然后,在NFS服务器上重新导出共享并重启NFS服务:

bash
sudo exportfs -a
sudo systemctl restart nfs-server  
# 或者你的NFS服务名称可能不同

最后,在客户端上重新挂载NFS共享,以确保应用了最新的权限设置。

Linux中常用的压缩工具

gzip和bzip2

不能压缩目录,只能一个一个文件进行压缩,压缩之后会使原文件消失

  • gzip * 压缩当前目录下所有的文件,但是目录不能压缩
  • gunzip * 解压当前目录下所有的.gz文件
  • bzip2 * 压缩当前目录下所有的文件,但是目录不能压缩
  • bunzip2 * 解压当前目录下所有的. bz2文件

tar工具

相关参数说明

  • z:用gzip来压缩/解压缩文件
  • j:用bzip2来压缩/解压缩文件
  • c:create,创建新的压缩文件,与x互斥使用
  • x:从压缩文件中释放文件,与c互斥使用
  • v:详细报告tar处理的文件信息
  • f:指定压缩文件的名字
  • t: 查看压缩包中有哪些文件

压缩

  • tar cvf 压缩包名字.tar 原材料[要打包压缩的文件或目录]
  • tar zcvf 压缩包名字.tar.gz 原材料[要打包压缩的文件或目录]
  • tar jcvf 压缩包名字.tar.bz2 原材料[要打包压缩的文件或目录]

解压缩

  • tar xvf 已有的压缩包(test.tar.gz)
  • tar zxvf 已有的压缩包(test.tar.gz)
  • tar jxvf 已有的压缩包(test.tar.bz2)
  • 解压到指定目录:添加参数 -C(大写)
    • tar zxvf test.tar.gz -C 解压目录(./mytest)
  • 查看压缩包中有哪些文件
    • tar -tvf test.tar

rar工具

使用前需要安装 rar 工具 sudo apt-get install rar

压缩

命令: rar a -r 要压缩的文件(含文件或者目录)

  • 压缩目录需要使用参数:-r
    • rar a -r my aa bb dir ----将aa bb dir压缩到my.rar文件中
  • 打包的生成的新文件不需要指定后缀

解压缩

  • 命令:rar x xxx.rar 压缩目录
    • rar x my.rar ----将my.rar解压到当前目录
  • 解压到指定目录,直接指定解压目录即可
    • rar x xxx.rar 目录
    • rar x my.rar TAR -----将my.rar解压到TAR目录

zip工具

压缩

zip -r 压缩包名 要压缩的文件(含文件或目录)
  • 压缩目录需要使用参数-r
  • 使用该命令不需要指定压缩包后缀
    • zip -r xxx file dir ---生成xxx.zip文件

解压缩

unzip 压缩包名
  • 解压缩到指定目录:添加参数 –d 解压目录
    • unzip xxx.zip -d /home/itcast/test/day1

面试题

如何理解一切皆文件

“一切皆文件”是Linux通过虚拟文件系统将硬件、进程等资源抽象为文件,提供统一操作接口的设计思想。例如,硬盘设备映射为/dev/sda文件,网络套接字用文件描述符管理,通过read/write即可读写。其优势在于简化开发(一套API操作所有资源)和系统管理(脚本化处理),但也需注意挂载要求和抽象性能损耗。

详细释义

本质:统一的资源抽象与接口标准化

资源抽象的统一性:Linux将所有硬件设备、进程、网络连接、内存等资源抽象为文件,例如:

  • 硬件设备:磁盘(/dev/sda)、终端(/dev/tty
  • 进程信息/proc/[pid]目录下的文件(如/proc/cpuinfo描述CPU信息)
  • 网络通信:套接字(Socket)被抽象为文件描述符
  • 虚拟资源:管道(Pipe)、符号链接(Symbolic Link)

这种抽象通过 虚拟文件系统(如/proc/sys/dev 实现,屏蔽了底层硬件差异

接口标准化:所有资源均可通过同一组文件操作接口访问,包括:

  • 基本操作open()打开、read()/write()读写、close()关闭
  • 控制操作ioctl()用于设备参数调整(如调整终端窗口大小)

开发者无需为不同资源编写专用代码,极大降低了开发复杂度


实现机制:文件描述符与虚拟文件系统

文件描述符(File Descriptor):每个打开的资源由内核分配唯一的整型文件描述符,作为资源操作的句柄。例如:网络套接字int sockfd = socket(...)返回描述符,后续读写均基于此

虚拟文件系统的角色

  • /proc:暴露进程和系统运行时信息(如/proc/meminfo显示内存状态)
  • /dev:管理硬件设备文件(如/dev/null模拟“黑洞”设备)
  • /sys:提供内核和硬件配置接口(如调整CPU频率)

实际应用与优势

简化系统操作

  • 通过统一命令操作资源:例如cat /proc/cpuinfo查看CPU信息,echo "data" > /dev/ttyS0向串口发送数据
  • 脚本化管理:批量操作文件化资源(如监控/proc/loadavg实现负载告警)

增强开发灵活性

  • 网络编程中,套接字与文件共享接口:read(sockfd, buffer)读取网络数据
  • 设备驱动开发:通过实现file_operations结构体定义设备行为(如自定义read()函数)

安全性控制

  • 统一的权限模型:通过chmodchown设置文件权限,控制资源访问
  • 安全扩展:结合SELinux限制进程对敏感文件(如设备文件)的访问

局限性

挂载必要性:外部设备(如U盘)需挂载到文件系统目录(如/mnt)方可访问,增加了操作步骤

抽象层性能损耗:文件接口的通用性可能牺牲特定设备的优化空间(如直接硬件访问比文件读写更快)


设计哲学的意义

“一切皆文件”体现了Linux简洁性、一致性与可扩展性的设计理念:

  • 对开发者:降低学习曲线,提升开发效率;
  • 对系统:统一资源管理模型,简化内核设计;
  • 对生态:促进工具链的统一(如grepawk可处理任意文件化资源)