Linux 介绍_3 文件系统

文件与文件系统

我的博客

将以如下几个部分进行讨论:

  • 描述 Linux 文件系统布局
  • 打印/设置路径
  • 描述最重要的文件,包括内核与 shell
  • 寻找/隐藏文件
  • 创建/移动/删除文件与目录
  • 展示文件内容
  • 理解使用不同的链接类型
  • 查看文件属性, 修改文件权限

Linux 文件系统总览

文件

一般文件

对于 UNIX 系统中的描述, 同样可以用来描述 Linux, 即:
UNIX 系统中, 一切皆文件; 不是文件的内容就是一个进程.

虽然存在特殊的文件看起来不只是一个文件(比如: 管道, 套接字), 但是为了保持简单, 一切皆文件这句话, 是没有问题的. 一个 Linux 系统, 就像 UNIX 系统, 目录与文件是一样的, 因为目录仅仅是包含文件或目录的文件. 程序, 服务, 文本, 图像等, 都是文件. 输入与输出设备, 以及所有的设备, 都是文件.

文件排序

大部分文件仅仅是文件, 称为常规文件; 他们包含常规的数据, 比如, 文本文件, 可执行文件, 程序文件, 从程序中输出或向程序输入等.

一些特殊的文件:

  • 目录: 包含其他文件的文件
  • 特殊文件: 用来输入/输出的机制, 最特殊的文件是 /dev 中的文件
  • 链接: 使同一个文件在系统文件树的多个部分查询到的一种方法
  • 套接字: 特殊的文件类型, 与 TCP/IP 套接字类似, 提供进程间通讯
  • 管道: 像套接字一样, 提供一种进程间通讯, 而不需要使用套接字机制

使用 ls -l, 打印文件类型, 第一个字符表示了文件类型:

Arvin@XDD:~$ ls -l
总用量 84
drwxrwxr-x  5 Arvin Arvin  4096 11月  2 09:37 hello
-rw-rw-r--  1 Arvin Arvin 64004 11月  2 09:37 pyshtables.py
drwxrwxr-x  2 Arvin Arvin  4096 11月 15 10:02 test
drwxrwxr-x 24 Arvin Arvin  4096 9月  30 17:07 unix_program

下表列出字符表示的文件类型:

字符 含义
- 常规文件
d 目录
l 链接
c 特殊文件
s 套接字
p 管道
b 块设备

作为一个系统使用者, 只需要处理普通文件, 可执行文件, 目录以及链接文件.

关于分区

为什么要有分区

很多人对分区的概念比较模糊, 很多操作系统都有能力创建或删除分区. Linux 在同一个盘上划分了多个分区, 现得有点奇怪, 因此需要进行解释说明.

多个分区的一个目标是为实现更高的数据安全性. 通过将硬盘划分成多个分区, 数据可以进行分组/隔离. 当意外发生时, 只有一个分区的数据会出问题, 其他分区的数据可以幸存.

这个原则可以追溯到 Linux 不具备日志文件系统的时期, 意外地掉电可能导致灾难. 分区的保留, 是为了保证安全与系统的鲁棒性, 因此, 当系统的一部分出现问题时, 并不意味着整个系统都出现问题. 这是现在分区保留的最主要原因. 一个简单的例子: 用户创建了一个脚本, 一段程序或一个 WEB 应用, 开始填充盘空间. 如果盘只包含有一个分区, 如果盘被填满时, 系统将会因此停止. 如果用户将数据保存在一个隔离的分区, 那么只有那个分区受影响, 其他分区依旧保留其原有的功能.

注意到, 具有一个日志文件系统只能在电力问题出现时, 提供数据安全性. 不会为数据坏块以及逻辑错提供保护措施. 在这样的情况下, 你应该使用一个 RAID Redundant Array of Inexpensive Disks 进行冗余备份.

分区布局与类型

Linux 系统中, 有两种主要分区:

  • 数据分区
    常规的 Linux 数据, 包括包含所有数据以及系统运行内容的根分区
  • 交换分区
    计算机的物理内存的扩展, 在硬盘上的额外的内存空间

大部分系统都包含一个根分区, 一个或多个数据分区以及一个或多个交换分区. 在混合环境中, 可能还包含其他系统的数据, 比如微软的 FATVFAT 文件系统.

大部分 Linux 系统使用 fdisk 在安装时设置分区类型. 在某些情况下, 你可能需要手动的进行分区类型选择, 甚至要进行实际的分区.

标准的根分区(以 / 标识), 大概有 100-500MB, 包含系统配置文件, 大部分基础命令以及一些程序, 系统库, 一些临时空间以及用户的家目录. 标准的安装需要大概 250MB 的根分区.

交换分区(使用 swap 标识)只有系统可以访问, 在常规操作下这个分区是隐藏的. 交换分区可以在无论什么情况发生, 保证系统的稳定运行. 在 Linux 中, 你很少会看到内存空间不足的提示信息, 就是因为这个额外的内存.

使用这个硬盘上的虚拟的内存空间, 相较于实际的内存空间, 肯定是要慢很多的.

Linux 一般会在硬盘空间中分配实例物理内存的两倍空间用作交换分区, 当安装一个系统时, 你必须了解你是怎样完成的. 比如你的系统具有 512MB 的 RAM 空间:

  • 第一种可能是单个的 1GB 交换分区
  • 第二种可能是两个 512MB 的交换分区
  • 第三种可能是两个硬盘, 每一个盘上具有一个 512MB 的交换分区

最后一个选择可能是比较好的选择.
一些应用, 比如数据库, 可能需要更多的交换分区空间. 其他的, 比如 一些手持设备的系统, 可能不具备任何的交换分区空间. 交换分区空间大小依赖于你的内核版本.

在一些发布版本中, 内核位于一个单独的分区. 因为这是系统最重要的文件. 如果你的系统是这样的系统, 那么你会看到一个 /boot 分区, 保有着你的内核以及相对应的数据文件.

硬盘的其他部分划分到数据分区, 这虽然会导致所有的非系统关键数据多归类到一个分区. 当非关键数据分布到不同的分区时, 通常具有如下的模式:

  • 一个分区为用户程序 /usr
  • 一个分区包含游湖的个人数据 /home
  • 一个分区存储临时数据, 比如日志等 /var
  • 一个分区包含第三方以及额外的软件 /opt

一旦具备了这些分区, 你只能添加更多的分区, 修改现有分区的大小或属性不提倡.

硬盘的分区的划分是由系统管理员确定的, 在比较大的系统中, 管理员可能使用合适的软件, 将多个硬盘划分到单个分区中. 大部分版本允许标准的工作站/服务器的配置选择, 但同时也接受定制化分区. 在安装过程中, 你可以定义你自己的分区布局.

一个工作站或客户端, 通常是为一个用户使用的. 选择安装的软件也会基于个人喜好, 比如桌面主题, 开发工具, 客户程序, 多媒体软件, web服务器等. 基本上所有的内容都放到一个单独的分区中, 交换分区空间是 RAM 空间的两倍大小.

在服务器上, 系统数据倾向于与用户数据分隔开来. 提供服务的程序保存在一个不同的空间. 不同的分区将会在这样的系统上创建:

  • 一个分区具有启动引导设备的数据
  • 一个分区配置数据以及服务器程序
  • 一个或多个分区包含服务器数据, 比如数据库表, 用户邮件, ftp 文档
  • 一个分区带有用户程序以及应用
  • 一个或多个分区包含指定用户的文件(家目录)
  • 一个或多个交换分区(虚拟内存)

服务器通常具有更多的内存, 因此也就具备更多的交换分区空间. 一个特别的继承, 比如数据库, 可能需要更多的交换分区空间, 查看指定文档对于这个内容的细节介绍.

挂载点

所有的分区都通过挂载点挂在系统上. 挂载点定义了文件系统中的特殊的数据集空间. 通常情况下, 所有的分区都链接到根分区上. 这个分区以 / 标识, 在这个分区下, 目录被创建出来. 这些空目录, 将会作为连接到他们的分区的起始点.

我们想在文件系统中, 希望连接分区到目录 /opt/media. 为了完成这个工作, 系统管理员必须确保目录 /opt/media 存在于系统上. 最好是一个空的目录. 然后使用 mount 命令, 管理员可以连接分区到系统. 当你查看之前还是空的目录 /opt/media, 它将包含挂在在这个目录上的内容.

在系统启动过程中, 所有的分区都是这样挂在的, 这个描述在 /etc/fstab 中. 一些分区并不是默认挂载的. 有的设备并不总是连接到设备上, 比如数码相机存储. 如果配置的好, 设备连接到系统上之后, 将会自动挂载.

在一个运行中的系统上, 分区信息以及他们的挂载点可以使用 df 命令打印出来. 在 Linux 中, dfGNU 版本, 支持 -h 选项, 来提供高可读性的打印信息.

df 命令只会打印非交换分区. 这些分区可以包括其他网络系统的分区. 下面的例子中, 家目录从网络文件服务器上挂载:

$ df -h
Filesystem          Size  Used Avail Use% Mounted on
/dev/hda8           496M  183M  288M  39% /
/dev/hda1           124M  8.4M  109M   8% /boot
/dev/hda5            19G   15G  2.7G  85% /opt
/dev/hda6           7.0G  5.4G  1.2G  81% /usr
/dev/hda7           3.7G  2.7G  867M  77% /var
fs1:/home           8.9G  3.7G  4.7G  44% /.automount/fs1/root/home

更多文件系统布局

常见目录介绍

为了方便, Linux 文件系统通常为树状结构. 在一个标准的 Linux 系统中, 你可能发现如下的文件系统:

/
├── bin
├── boot
├── dev
├── etc
│   ├── default
│   ├── rc.d
│   ├── sound
│   ├── sysconfig
│   └── x11
├── home
│   ├── anna
│   ├── bob
│   ├── emmy
│   └── rick
├── lib
├── lost+found
├── misc
├── mnt
│   ├── cdrom
│   └── floppy
├── net
├── opt
├── proc
├── root
├── sbin
├── tmp
├── usr
│   ├── bin
│   ├── games
│   ├── include
│   ├── lib
│   ├── local
│   ├── man
│   ├── sbin
│   ├── share
│   │   └── doc
│   ├── src
│   └── x11R6
└── var
    ├── gmd
    ├── lib
    ├── lock
    ├── log
    ├── run
    ├── spool
    └── tmp

这是一个 RedHat 系统的文件系统布局.

文件系统起点为 / 根目录, 根目录下面的目录都具备特殊的含义, 如下表:

目录 内容
/bin 常用程序, 由系统/系统管理员/用户共享
/boot 起始文件以及内核 vmlinuz, 在新的版本中还有 grub 数据
/dev 包含所有的 CPU 外设硬件, 它们表现为具有特殊属性的文件
/etc 最重要的系统配置文件都位于 /etc
/home 一般用户的家目录
/initrd 引导信息
/lib 库文件, 包含所有类型程序需要的文件
/lost+found 每一个分区在它的上层目录上都具备一个 /lost+found, 文件失败保存在这里
/misc 各种各样的文件
/mnt 标准外部文件挂载点
/net 远程文件系统的标准挂载点
/opt 包含第三方软件以及其他数据
/proc 虚拟文件系统, 包含系统资源的信息
/root 管理员用户家目录, 区分 / 与这个目录
/sbin 系统以及系统管理员使用的程序
/tmp 系统使用的临时空间, reboot 重启后数据丢失
/usr 程序, 库, 文档等
/var 存储所有的可变文件以及由用户创建的临时文件, 比如日志文件等

通过 df 命令可以查看目录所处的分区, 比如 df -h . 展示当前目录所在的分区.

实际的文件系统

对于大部分用户来说, 文件与目录是以树状结构生长这一概念是可以理解的. 但是对于计算机而言, 什么是树状结构是抽象的概念.

每一个分区都具有它自己的文件系统. 通过将这个文件系统连接到一起, 我们可以想象出一个树状的结构, 但是文件系统并不只是表象的这么简单. 在一个文件系统中, 一个文件通过一个 inode 节点进行表示, 一个序列编号包含实际组成文件的数据, 文件属于谁, 文件位于硬盘的什么位置等信息.

每一个分区都具有自己的 inode 集.

每一个 inode 描述硬盘上的数据结构, 存储文件的属性, 包括文件数据的物理位置. 当一个硬盘初始化来接收存储的数据, 通常在初始化系统安装过程中, 或当添加额外的盘到系统中, 将对分区创建一个固定的 inode 数字. 这个数字表示该分区同时具有的最多的文件(包括目录, 特殊文件, 连接等)数量. 我们通常在每个存储的 2-8 千字节分给一个 inode.

当一个新文件创建时, 获取到一个自由的 inode. 在这个 inode 中具有如下的信息:

  • 文件持有者以及组持有者
  • 文件类型(常规文件, 目录, ...)
  • 文件权限
  • 创建日期与实践, 最后读取以及修改时间
  • inode 中的信息改变的时间日期
  • 到这个文件的链接数量
  • 文件大小
  • 定义实际文件数据的地址

唯一没有在 inode 中包括的数据是, 文件名以及目录. 这些存储在特殊的目录文件中. 通过比较文件名以及 inode 号, 系统能够生成一个树状结构. 用户可以通过使用 ls -i 查看 inode.

文件系统的方向

路径

当你想要系统执行某个命令, 比如 ls 时, 不需要指定这个命令在什么位置, 去哪里找这个命令. 我们知道 ls 命令位于 /bin 目录中, 这一信息可以通过执行 which -a ls 命令打印出来, 我们在执行 ls 时, 不需要输入 /bin/ls 来执行这个命令.

这是因为 PATH 环境变量会帮助你完成这个操作. 这个变量列出系统的可执行文件的查找位置. 通过 echo $PATH 可以查看这个环境变量:

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

在这个例子中, 会依次在目录 /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /usr/games /usr/local/games /snap/bin 中查找可执行的命令. 只要一找到匹配的命令, 就结束寻找, 即使没有编历所有的目录.
在下面的例子中, 用户知道有一个程序名为 sendsms 来发送 SMS 信息, 在系统上的另一个用户可以使用, 但是她不能用. 唯一的区别是对 PATH 变量的配置:

[jenny@blob jenny]$ sendsms
bash: sendsms: command not found
[jenny@blob jenny]$ echo $PATH
/bin:/usr/bin:/usr/bin/X11:/usr/X11R6/bin:/home/jenny/bin

[jenny@blob jenny]$ su - tony
Password:

tony:~>which sendsms
sendsms is /usr/local/bin/sendsms
tony:~>echo $PATH
/home/tony/bin.Linux:/home/tony/bin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:/usr/bin:/usr/sbin:/bin:/sbin

注意到, 使用 su 命令可以在 shell 中切换另一个用户身份进行操作, 当然, 前提是你知道这个用户的密码.

下面的例子中, 一个用户想要使用 wc 命令来检查一个文件中具有的行数, 但在执行时却没有打印内容, 因此, 他通过 Ctrl+C 组合键终止了这个过程:

jumper:~> wc -l test
(Ctrl-C)
jumper:~> which wc
wc is hashed (/home/jumper/bin/wc)
jumper:~> echo $PATH
/home/jumper/bin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:/usr/bin:/usr/sbin:/bin:/sbin

使用 wihch 命令, 查看到在他的家目录下, 具有一个 /bin 目录, 包含着名称也是 wc 的可执行文件. 因为这个目录排在真正想要执行的 wc 所在目录的前面, 因此, 没有等到找到真正的这个命令, 就已经执行了。如果此时他希望执行 wc 命令,那么要么修改他自己的 wc 名称,要么,在执行 wc 命令时,给定这个命令的完整路径。

如果用户使用其他目录中的命令更加频繁,那么他可以修改 PATH 的排列顺序:

jumper:~> export PATH=/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:/usr/bin:/usr/sbin:/bin:/sbin:/home/jumper/bin

注意: 使用 export 命令修改这个 PATH 并不是永恒的,只在本次会话中有效。打开新的会话,这个 PATH 并不会出现在新的会话中。后面我们会讲到如何真正的修改一个环境变量。

绝对路径与相对路径

在指向一个文件时,我们可以使用从根目录发展出来的一个树状的结构进行表述。这个情况下,路径从 / 开始,称为绝对路径,这样的路径唯一确定一个文件。

其他情况下,路径不以 / 开始,从家目录的 ~/bin/wc 以及在 /usr 中的 bin/wc,可能会使人义务,不以 / 路径开始的路径,称为相对路径。

在相对路径中,我们会使用 . 以及 .. 来分别表示当前目录,以及上层目录。例子如下:

  • 当你希望汇编源代码,文档通常指示你运行命令 ./configure,这个命令将执行当前目录下的 configure 可执行文件
  • HTML 文件中,相对路径通常用来指向页面需要的资源所在的位置:
    <img alt="Garden with trees" src="../images/garden.jpg">
    

最重要的文件与目录

内核

内核是系统的核心。它管理底层硬件与外围设备间的通讯。内核也确保进程以及守护进程能够在正确的时间点开始与终止。设计内容太多,这个文档不再展开。

shell

什么是 shell

什么是 shell,你在互联网上搜索可能有多种解释。shell 是与电脑交互的一种方法,它是一种语言。通过 shell 可以与系统进行交流,shell 允许用户以灵活的方式处理系统。

shell 类型

就像很多人知道有不同的语言与方言,同样,也存在多种 shell:

  • sh Bourne Shell,最初的 shell 现在依旧被 UNIX 使用
  • bash Bourne Again SHell 标准的 GNU shell,直观且灵活。在 Linux 中,bash 是一般用户的标准 shell,这个 shell 也称为 sh 的超集,它具有 sh 的特性,并添加了更多的功能,bash 兼容 sh,能在 sh 中运行的命令,都能够在 bash 中运行。
  • csh C Shell 这个 shell 的语法类似于 C 语言
  • tcsh Turbo C Shellcsh 的超集
  • ksh Korn Shell sh 的超集

在文件 /etc/shells 中,给出了在 Linux 系统中已知的的 shell

$ cat /etc/shells
/bin/sh
/bin/bash

你的默认 shell/etc/passwd 文件中设置:

Arvin@XDD:~$ cat /etc/passwd | grep bash
Arvin:x:6002:6002::/home/Arvin:/bin/bash

想要切换使用的 shell 到另一个 shell,只需要在终端中输入要使用的新 shell 的名称九课。

当前正在使用的shell

如果不确定当前使用的 shell,只需要执行如下的命令:

Arvin@XDD:~$ echo $SHELL
/bin/bash

你的家目录

你的家目录,是你连接到系统后的默认路径。在大部分情况下,它是 /home 目录的子目录。当然也有其他的情况,如果你的家目录可能位于远程文件服务器的硬盘上,这种情况下,你可能发现你的家目录为 /nethome/your_user_name。当然,你的系统管理员可能给你分配了更加奇怪的家目录 /disk6/HU/07/jgillard

无论你的家目录是什么样,都无需担心。你的家目录的正确路径存储在 HOME 环境变量中。通过 echo 命令,可以查看这个变量:

Arvin@XDD:~$ echo $HOME
/home/Arvin

在你自己的家目录,只要分区允许,你可以为所欲为。系统管理员可能对你的分区进行了限制。

最重要的配置文件

之前我们提过,大部分配置文件存储在 /etc 目录下。通过 cat 命令,可以查看配置文件中的具体内容。

下面将会介绍一些比较重要的配置文件,一些文件也可能有 man 帮助页面,比如 man group

文件 信息/服务
aliases 邮件别名文件,Sendmail 以及 Postmail 服务器使用
apache Apache WEB服务器的配置文件
bashrc bash 的系统维度的配置文件
crontab, cron.* 需要周期性执行的任务配置文件,备份,更新系统数据库,清理系统等
default 指定命令的默认选项, 比如 useradd
filesystems 已知文件系统: ext3, vfat, iso9660等
fstab 分区列表以及它们的挂载点
ftp* ftp 服务器的配置文件,哪些人可以连接等
group 用户组配置文件
hosts 使用网络可以连接的设备,而不需要域名服务
inittab 开机信息,模式,文本控制台数量
issue 版本信息
ld.so.conf 库文件位置
lilo.conf,silo.conf,aboot.conf Linux Loader 启动信息
logrotate.* 日志文件相关
mail 邮件服务器的行为
modules.conf 模块的配置,使能某种特性(驱动)
motd 展示谁连接到了系统
mtab 当前挂载的文件系统,建议永远不要编辑这个文件
nsswitch.conf 当一个进程需要解析主机名时,解析顺序
pam.d 认证模块的配置
passwd 本地用户列表
printcap *
profile shell 环境的系统维度的配置文件,变量,新文件的默认属性,资源的限制等
rc* 定义每一个运行等级活跃的服务
resolv.conf 顺序连接的 DNS 服务器
sendmail.cf Sendmail 服务器的主配置文件
services 这个设备开放的端口服务
sndconfig/sound 声卡以及声音事件的配置文件
ssh secure shell 客户端与服务器的配置文件
sysconfig 包含系统配置文件,鼠标,键盘,网络,桌面,系统时钟,电源管理等
X11 图形服务器设置
xinetd.*/inetd.conf 网络服务配置文件

最常用的设备

连接到 PC 的每一个外设,都在 /dev 目录中呈现。下面的表格介绍一些常见的外设:

名称 设备
cdrom CD 驱动
console 当前使用的控制台的特殊入口
cua* 特殊端口
dsp* 采样记录设备
fd* 软盘驱动的入口,默认为 /dev/fd0
hd[a-t][1-16] 标准的 IDE 驱动
ir* 红外设备
lp* 打印机
mem 内存
midi* 媒体播放器
mixer*/music 混频器模型
modem 调制解调器
mouse/msmouse 鼠标
null 无底垃圾箱
par* 并行端口入口
pty* 伪终端
radio* 无线电设备
ram* 启动设备
sd* SCSI 盘
sequencer 声音设备
tty* 虚拟控制台
usb* USB卡以及扫描器
video* 显卡支持

最常用的变量文件

/var 目录中,我们找到一系列的目录,用来存储特殊的不断变化的数据。比如日志文件,邮箱等。

为了安全起见,这些文件通常与主文件系统分隔开。一些文件需要具有更多的权限,比如 /var/tmp 需要对所有的用户开放写权限。这也是将这个分区单独分隔开的原因,可以放置比如邮件轰炸等危险而占满文件系统。

/var/tmp 以及 /tmp
/tmp 中的文件在重启或执行常规的系统任务时被删除。一些系统中 /var/tmp 中的文件的行为也是不可预测的。建议使用 /var/tmp 目录存放临时文件。
无论你做什么,试着以普通用户的权限进行操作-不要将文件存储在 / 根目录下。不要将它们放在 /usr 或它的子目录下。

UNIX 系统中,同样也是在 Linux 系统中,一个主要的安全措施是,日志记录存留功能,它记录所有用户的行为,处理内容,系统日志等。syslogdaemon 配置文件确定保留哪个以及多长的日志信息。日志的默认位置是 /var/log,包括不同的日志,访问日志,服务日志等。

我们通常在 /var 目录中能够找到服务器数据,它保存在这里,能够确保它与危险的数据比如服务器程序及其配置文件分隔开。一个典型的例子是 /var/www,包含真正的WEB服务器提供的 HTML 页面,脚本以及图像。因为这些数据通常是公有可访问,且总是改变的,保存在这里比较安全。

在大部分工作站,/var/spool 至少包含一个 at 以及 cron 目录,包含定时任务。在办公环境中,它通常还包括 lpd,保存着打印队列以及打印机配置文件,以及打印机日志文件。

在服务器系统中,我们一般能看到 /var/spool/mail 目录,包含本地用户收到的邮件,每一个用户有自己的一个文件,即该用户的收件箱。与其相关的目录是 mqueue,存储尚未发送的邮件信息。

在基于红帽 RPM 的版本还具有 /var/lib/rpm 目录,RPM 包信息存储在这个位置。其他的包管理通常在 var 中也具有存储自己数据的位置。


操作文件

查看文件属性

ls 更多功能

除了展示文件的名称,ls 可以给出一些其他的信息,比如我们已经讨论过的文件类型。它也可以展示文件权限,文件大小,文件的 inode,创建日期时间,文件拥有者以及文件的链接数等信息。使用 ls-a 选项,文件的隐藏信息将一览无余,同时以 . 开头的隐藏文件也得以呈现。每一个目录都包含一个 . 以及 ..,这用来确定它们的在文件系统树结构的目录位置。

你可以阅读 lsinfo 页面,因为在使用 Linux 时,会反复地使用这个命令。命令的选项是可以组合的。ls 常用的选项组合是 ls -al,展示文件以及文件属性以及符号链接指向的路径。ls -latr 展示相同的信息,只是顺序与上一个命令正相反。

在大部分的 Linux 版本中,ls 命令是带有颜色属性的,这个特性方便不使用 ls 的任何选项,查看文件类型。为了实现这样的功能,每一类文件必然有它自己的颜色,标准的主题色在 /etc/DIR_COLORS 中配置。

颜色 文件类型
蓝色 目录
红色 压缩文件
白色 文本文件
粉色 图像
青色 链接
黄色 设备
绿色 可执行文件
闪烁红色 断开的链接

在没有颜色使用时,为了增加可读性,会使用如下的方案:

字符 文件类型
常规文件
/ 目录
* 可执行文件
@ 链接文件
= 套接字
` `

更多工具

为了查看我们正在处理的数据的更多的信息,可以使用 file 命令。file 尝试猜一个文件的类型:

mike:~> file Documents/
Documents/: directory
mike:~> file high-tech-stats.pdf
high-tech-stats.pdf: PDF document, version 1.2
mike:~> file Nari-288.rm
Nari-288.rm: RealMedia file
mike:~> file bijlage10.sdw
bijlage10.sdw: Microsoft Office Document
mike:~> file logo.xcf
logo.xcf: GIMP XCF image data, version 0, 150 x 38, RGB Color
mike:~> file cv.txt
cv.txt: ISO-8859 text
mike:~> file image.png
image.png: PNG image data, 616 x 862, 8-bit grayscale, non-interlaced
mike:~> file figure
figure: ASCII text
mike:~> file me+tux.jpg
me+tux.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI),
            "28 Jun 1999", 144 x 144
mike:~> file 42.zip.gz
42.zip.gz: gzip compressed data, deflated, original filename,
         `42.zip', last modified: Thu Nov  1 23:45:39 2001, os: Unix
mike:~> file vi.gif
vi.gif: GIF image data, version 89a, 88 x 31
mike:~> file slide1
slide1: HTML document text
mike:~> file template.xls
template.xls: Microsoft Office Document
mike:~> file abook.ps
abook.ps: PostScript document text conforming at level 2.0
mike:~> file /dev/log
/dev/log: socket
mike:~> file /dev/hda
/dev/hda: block special (3/0)

file 命令也具有很多选项,其中 -z 可以用来查看压缩文件中的内容。

创建/删除文件/目录

制造一个混乱

现在,几乎每一个系统都链接到了网络,因此都会从一台设备复制到另一台设备上。因此会需要反复的创建、删除文件。

工具

创建目录

通过 mkdir 命令创建目录:

richard:~> mkdir archive
richard:~> ls -ld archive
drwxrwxrwx  2 richard richard           4096 Jan 13 14:09 archive/

使用 -p 选项创建目录以及目录的子目录:

richard:~> cd archive
richard:~/archive> mkdir 1999 2000 2001
richard:~/archive> ls
1999/  2000/  2001/
richard:~/archive> mkdir 2001/reports/Restaurants-Michelin/
mkdir: cannot create directory 2001/reports/Restaurants-Michelin/:
No such file or directory
richard:~/archive> mkdir -p 2001/reports/Restaurants-Michelin/
richard:~/archive> ls 2001/reports/
Restaurants-Michelin/
移动文件

使用 mv 命令来移动文件、目录。

richard:~/archive> mv ../report[1-4].doc reports/Restaurants-Michelin/

这个命令也可以用来重命名文件:

richard:~> ls To_Do
-rw-rw-r--    1 richard richard      2534 Jan 15 12:39 To_Do
richard:~> mv To_Do done
richard:~> ls -l done
-rw-rw-r--    1 richard richard      2534 Jan 15 12:39 done

可以看到只有文件的名称改变了,其他的属性保留。

复制文件

使用 cp 命令复制文件或目录,一个很有用的选项可以实现递归的复制目录下的所有子目录、文件。即 -R 选项,一般的语法是:

cp [-R] fromfile tofile
移除文件

使用 rm 命令来移除单个文件,rmdir 来移除空目录。rm 命令也可以通过选项移除非空目录。

查找文件

使用 shell 特性

前面提到过的 TAB 特性。

which

使用 which 命令,可以在用户查找路径下给出的目录寻找需要的文件。当然,因为查找路径只包含可执行程序的路径,因此 which 命令不能用来查找常规的文件。当执行命令时,出现 Command not Found 报错时,这个命令十分有用。

tina:~> which acroread
/usr/bin/which: no acroread in (/bin:/usr/bin:/usr/bin/X11)

find

这两个命令是真正高效的查找工具。find 命令不仅允许用户查找文件名,它还接受文件大小,上次修改日期以及其他文件属性作为查找的标准。最常用的方法是通过文件名进行搜索:

find <给定查找路径> -name <待查找字串>

这个命令的执行,将会递归地在指定路径目录及其子目录查找待查找字串。

可以通过 find 按照文件大小进行查找,下面的例子,在本目录下查找 5MB 以上的文件:

find . -size +5000K

find 命令可以对查找到的文件执行特定操作,常用的方式是移除文件。

find . -name "*.tmp" -exec rm {} \;

grep

一般的行过滤

grep 是一个强力的程序,可以用来过滤输入内容,返回期望的特定模式输出。下面的例子通过 grep 在文件 .bash_history 中查找带有 find 的字串:

$ grep -a find .bash_history
# 输出等同于
$ cat .bash_history | grep find
特殊字符

shell 中具有特殊含义的字符必须进行转义,在 bash 中转义字符是 \,使用转义字符将会移除字符自身具备的特殊含义。比如,在 shell 中的 /.?以及 * 等字符。
比如,你想要查看文件 * 的内容,而不是目录中的所有文件的内容,就可以使用如下的命令:

less \*

更多的方式查看文件内容

一般方式

除了 cat 这种将文件内容打印到标准输出的命令,还有其他的命令可以用来查看文件内容。
字体问题 富文本工具通常会遇到一个问题,即文字的编码方式。特殊的字符,比如一些特殊的字母,中文以及其他不是 en_US 编码方式的字符,可能会展示出错。当然现在有了更加先进的字符编码方式,可以减少这种情况发生。

less

UNIX 历史上,出现的工具顺序是这样的:

  • 首先是 cat,以一种不可控方式进行流输出
  • 之后是 pg,这个工具在一些老版本的 UNIX 上可能还会看到,这个命令一次输出一页内容
  • more 工具作为 pg 的升级版本,在很多 Linux 版本上依旧可以看到
  • lessGNU 版本的 more,具有一些独有的特性,允许高亮搜索的字串,回滚等,使用方式十分简单:
    less name_of_file
    

head 以及 tail

这两个命令展示前 n 行,或后 n 行文件内容。查看最后 10 条历史命令:

tail -10 .bash_history

head 使用方式类似。

链接文件

链接类型

链接是将两个或多个文件名来访问同一个数据资源的一种方式。有两种实现方式:

  • 硬链接
    通过相同的 inode 关联两个或多个文件名,它们的行为像是独立的文件,硬链接共享硬盘上的相同数据块。
    硬链接不能跨分区,因为 inode 号在分区中是唯一的。
  • 软连接/符号链接
    使用一个小的文件指针,指向另一个文件。一个符号链接包含指向目标文件的路径,而不是指向文件所在硬盘的物理位置。软链接可以跨分区。

每一个常规文件理论上都是一个硬链接。硬链接不能够跨分区。

需要提一嘴的是,第三种类型的链接,用户空间链接,类似于 MS Windows 中的快捷方式。这些文件包含的元数据,只能被图形文件管理器解析。对于内核以及 shell 而言,这些只是常规的文件,它们可能以 .desktop.lnk 作为后缀名。

创建符号链接

通过如下命令创建符号文件的符号链接:

ln -s targetfile linkname

在下面的例子中,用户 freddy 创建在他自己家目录的子目录下创建了系统上其他目录的一个软连接:

freddy:~/music$ ln -s /opt/mp3/Queen/ Queen
freddy:~/music$ ls -l
lrwxrwxrwx  1 freddy  freddy  17 Jan 22 11:07 Queen -> /opt/mp3/Queen

符号链接是非常小的文件,硬链接与源文件具有相同的大小。

符号链接通常用来节省盘空间,以方便复制一个文件,满足安装新程序时对某特定路径上文件的依赖。

数据安全

访问权限: Linux 的第一道防线

在一台 Linux 系统中,每一个文件被一个用户以及组用户拥有。用户具有第三种范畴,这样的用户,即不是拥有者,也不是组成员,这样的用户称为其他用户。对于指定类型的用户,读、写、执行权限可以分别指定。

我们已经使用 ls l 命令来查看文件的信息了,这个命令陈列的信息,包含文件对三种不同用户的权限,它们通过紧跟在第一个字符之后的 9 个字符进行标识。下面的例子中,rw-rw-r-- 中的头三个字符 rw- 表示文件拥有者的权限,中间三个字符 rw- 是文件组用户的权限,最后三个字符 r-- 为其他人的权限。这几个字符是 r w x,分别表示读、写、执行权限。

marise:~$ ls -l To_Do
-rw-rw-r--    1 marise  users      5 Jan 15 12:39 To_Do

marise:~$ ls -l /bin/ls
-rwxr-xr-x    1 root    root   45948 Aug  9 15:01 /bin/ls*

上面的例子中,第一个文件 To_Do 是常规文件,用户 marise 或在 users 组中的用户,因为具有 rw- 权限,可以读、写这个文件,但是不能执行这个文件;而其他人,因为只具有 r-- 权限,只对文件具有读权限。

上面的例子中,第二个文件 /bin/ls 是一个可执行文件,依据文件拥有者 root 权限 rwx,组 root 权限 r-x,以及其他人权限 --x。可以看出,所有人都可以执行这个程序,但是必须是 root 用户才可以修改这个文件。

为了方便使用,访问权限或模式以及用户组都具有对应的码,如下表所示:

编码1 编码2 含义
0 - 没有对应的访问权限
4 r 具有读权限
2 w 具有写权限
1 x 具有执行权限
编码 含义
u 文件拥有者
g 文件所属组
o 其他人

你可以通过 id 命令来查看自己的用户 id 以及所属的组。

Arvin@XDD:~$ id
uid=6002(Arvin) gid=6002(Arvin) groups=6002(Arvin)

当然也可以通过 echo 显式打印自己的用户名:

Arvin@XDD:~$ echo $USER
Arvin

工具

chmod

上面提到了文件具有的权限,我们可以使用 chmod 命令来修改文件具有的权限。chmod 命令支持字母形式的权限配置,同时也支持数字形式的权限配置。

下面的例子,我们使用字母形式的权限配置方法来配置权限,为用户添加文件的可执行权限:

$ ./hello
bash: ./hello: bad interpreter: Permission denied

$ cat hello
#!/bin/bash
echo "Hello, World"

$ ls -l hello
-rw-rw-r--    1 asim    asim    32 Jan 15 16:29 hello

$ chmod u+x hello
$ ./hello
Hello, World

$ ls -l hello
-rwxrw-r--   1 asim    asim    32 Jan 15 16:29 hello*

+- 操作符用来添加或删除文件对指定用户如 ugo 所具有的权限。下面的例子,对文件 hello 的拥有者添加读、写、执行权限,对组以及其他用户移除所有权限:

$ chmod u+rwx, go-rwx hello

$ ls -l hello
-rwx------    1 asim    asim    32 Jan 15 16:29 hello*

通常在对一个文件进行访问时,提示权限不够,就是因为你对文件的访问权限没有对应的访问权限,导致的报错。

chmod 的数字形式修改文件的权限时,以数字对应指定的权限:

命令 含义
chmod 400 file 拥有者只读,其他用户没有任何权限
chmod 500 directory 目录拥有者此时不能移除、重命名此目录中的文件
chmod 600 file 只有拥有者才能对文件读、写
chmod 644 file 拥有者可以读写文件,组用户、其他用户只能读文件
chmod 660 file 拥有者、组成员可以读写文件
chmod 700 file 文件可以被拥有者读、写、执行
chmod 755 file 拥有者可读、写、执行,组成员、其他用户只能读、执行文件
chmod 775 file 拥有者、组成员可以读、写执行文件,其他用户只能读、执行文件
chmod 777 file 所有人可以对文件进行读、写、执行

登录到另一个组

当你使用 id 命令,会打印你这个用户所属的所有组。在 Linux 中,你只能以一个组中的成员身份进行活动。默认情况下是在 /etc/passwd 文件中分配的组成员身份。可以在 /etc/group 文件中查找其他对应的组身份:

$ id
uid=501(asim) gid=501(asim) groups=100(users),501(asim),3400(web)

$ grep asim /etc/passwd
asim:x:501:501:Asim El Baraka:/home/asim:/bin/bash

$ grep 501 /etc/group
asim:x:501:

上面的例子中,用户 asim 默认属于 asim 组,除了这个组,他还可以切换到 users 以及 web 组,使用 newgrp 来以其他的组成员身份登录:

$ newgrp web

$ id
uid=501(asim) gid=3400(web) groups=100(users),501(asim),3400(web)

在切换身份所属的组之后,创建的文件所属关系也会变化:

$ touch test
$ ls -l test
-rw-rw-r--  1 asim web   0 Jun 10 15:38 test

文件屏蔽码

在创建新文件时,标准文件权限由 mask 确定,通过 umask 命令可以查看这个值:

$ umask
0002

umask 的值用来计算新创建文件,文件默认拥有的权限。在上面的例子中,我们看到展示出来有4个数字,然而只有三个待分配权限的用户: 文件拥有者、组拥有者、其他人。第一个 0 是一个特殊的文件属性设置值,在后面会继续讨论。现阶段,就当第一个数字没有在你的系统上打印出来吧。那么你只看到 002 数值,创建新的权限会使用最多拥有的权限数值,减去这个 002 的数值。

在创建文件、目录时,Linux 默认会保证所有的用户对文件具有读、写权限,即 666 rw-rw-rw-;且会保证所有的用户对目录具有读、写、执行权限,即 777 rwxrwxrwx。通过使用这些默认的权限值减去 umask 值,得到文件具有的真正权限:

$ umask 
0002
$ touch hello
$ mkdir test

$ ls -l
-rw-rw-r-- 1 Arvin Arvin    0 12月 25 20:36 hello
drwxrwxr-x 2 Arvin Arvin 4096 12月 25 20:39 test

修改用户与组所有权

当文件被错误的用户或组拥有时,可以通过 chown 以及 chgrp 命令修正。chown 命令可以用来修改文件的拥有者以及组,chgrp 只会修改文件所属的组,不会修改文件拥有者。

chowm newuser file

如果使 chown 时,使用了冒号,并提供新的组,那么也会修改组拥有者:

jacky:~> id
uid=1304(jacky) gid=(1304) groups=1304(jacky),2034(pproject)

jacky:~> ls -l my_report
-rw-rw-r--  1 jacky   project       29387 Jan 15 09:34 my_report

jacky:~> chown jacky: my_report
jacky:~> chmod o-r my_report
jacky:~> ls -l my_report
-rw-rw----  1 jacky   jacky         29387 Jan 15 09:34 my_report

可以使用 chgrp 命令修改文件的组:

jacky:~> ls -l report-20020115.xls
-rw-rw---- 1 jacky   jacky   45635 Jan 15 09:35 report-20020115.xls

jacky:~> chgrp project report-20020115.xls
jacky:~> chmod o= report-20020115.xls
jacky:~> ls -l report-20020115.xls
posted @ 2021-12-23 21:34  ArvinDu  阅读(132)  评论(0编辑  收藏  举报