David Both 发布的文章

学习如何在 Apache 上托管你自己的网站,这是一个可靠、流行且易于配置的 Web 服务器。

我托管自己的网站已经有很多年了。自从 20 多年前从 OS/2 切换到 Linux 以来,我一直将 Apache 作为我的服务器软件。Apache 是可靠、流行的,且基本的安装配置也很容易。对于更复杂的设置(比如多个网站)也并不是那么困难。

Apache Web 服务器的安装和配置必须以 root 身份执行。 防火墙的配置也需要以 root 身份执行。 使用浏览器查看安装配置的结果应该以非 root 用户的身份完成。 (我在我的虚拟主机上使用 student 这个用户。)

安装

注意:我使用的实验环境是安装有 Fedora 27 的虚拟机,Apache 版本为 2.4.29。 如果您使用的是不同的发行版或不同版本的 Fedora,您的命令以及配置文件的位置和内容可能会有所不同。 但是,您需要修改的配置行是相同的。

Apache Web 服务器非常容易安装。 在我的 CentOS 6.x 服务器上,它只需要一个简单的 yum 命令。 它会安装所有必要的依赖(如果需要的话)。 我在我的 Fedora 虚拟机上使用了下面的 dnf 命令。 除了命令本身的名称之外, dnfyum 的语法是相同的。

dnf -y install httpd

这个虚拟机是个非常基础的桌面环境,我正在使用它作为编写书籍的测试平台。 即使在这个系统上,也只安装了六个依赖项,用了一分钟。

Apache 的所有配置文件都位于 /etc/httpd/conf/etc/httpd/conf.d 。网站的数据默认位于 /var/www,但如果你愿意,你可以改变它。

配置

Apache 主要的配置文件是 /etc/httpd/conf/httpd.conf 。 它包含许多在基本安装中不需要更改的配置。 实际上,只需对此文件进行一些更改即可启动并运行一个简单的网站。 该文件非常大,因此,我不会将这篇文章与大量不必要的东西混淆起来,而只会显示那些需要更改的指令。

首先,花点时间熟悉一下 httpd.conf 文件。我喜欢 Red Hat 的一个原因是它的配置文件注释非常的详细。 httpd.conf 文件也不例外,因为它有很好的注释。可以使用这些注释来了解文件的配置。

第一个要修改的是 Listen 配置项,它定义了 Apache 要监听页面请求的 IP 地址和端口。 现在,你只需要使这个网站可以从本地访问,所以使用 localhost 地址。 完成后,该行应该看起来像这样:( LCTT 译注:localhost 的 IP 地址是 127.0.0.180 是端口)

Listen 127.0.0.1:80

通过将此配置项设置为 localhost的 IP 地址,Apache 将只侦听来自本地主机的连接。 如果您希望 Web 服务器侦听来自远程主机的连接,则可以使用主机的外部 IP 地址。

DocumentRoot 配置项指定组成网站页面的 HTML 文件的位置。 该配置项不需要更改,因为它已经指向标准位置。 该行应该看起来像这样:

DocumentRoot "/var/www/html"

Apache 安装包会创建 /var/www 目录。 如果您想更改存储网站文件的位置,则使用此配置项来完成此操作。 例如,您可能想要为 www 目录使用不同的名称,以更明确地识别网站。 这可以是这样的:

DocumentRoot "/var/mywebsite/html"

这些是创建一个简单网站需要唯一修改的 Apache 配置项。 对于这个小练习,只对 httpd.conf 文件(Listen 配置项)进行了一些修改。 其它的配置项对于一个简单的 Web 服务器暂时无需配置。

另一个需要改变的地方是:在我们的防火墙中打开端口 80。 我使用 iptables 作为我的防火墙,因此我更改 /etc/sysconfig/iptables 文件以添加允许使用 HTTP 协议。 整个文件看起来像这样:

# sample configuration for iptables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

我在文件的倒数第三行上添加了一个新行,它允许在端口 80 上输入流量。现在我重新加载 iptables 配置文件。

[root@testvm1 ~]# cd /etc/sysconfig/ ; iptables-restore iptables

创建 index.html 文件

index.html 文件是你使用域名访问网站而不是访问特定网页时的默认文件。在 /var/www/html中,创建一个名字为 index.html 的文件,在其中添加字符串 Hello World 。你不需要添加任何的 HTML 标志去完成这项工作。web 服务器的唯一任务是提供文本数据流,服务器不知道数据是什么,也不知道如何呈现它。它只是将数据流传输给请求主机。

保存文件后,将所有权设置为 apache.apache

[root@testvm1 html]# chown apache.apache index.html

启动 Apache

Apache 很容易启动。 当前版本的 Fedora 使用 systemd 。 运行以下命令启动它,然后检查服务器的状态:(LCTT 译注:systemctl 是一个 systemd 工具)

[root@testvm1 ~]# systemctl start httpd
[root@testvm1 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2018-02-08 13:18:54 EST; 5s ago
     Docs: man:httpd.service(8)
 Main PID: 27107 (httpd)
   Status: "Processing requests..."
    Tasks: 213 (limit: 4915)
   CGroup: /system.slice/httpd.service
           ├─27107 /usr/sbin/httpd -DFOREGROUND
           ├─27108 /usr/sbin/httpd -DFOREGROUND
           ├─27109 /usr/sbin/httpd -DFOREGROUND
           ├─27110 /usr/sbin/httpd -DFOREGROUND
           └─27111 /usr/sbin/httpd -DFOREGROUND

Feb 08 13:18:54 testvm1 systemd[1]: Starting The Apache HTTP Server...
Feb 08 13:18:54 testvm1 systemd[1]: Started The Apache HTTP Server.

您的服务器上的命令可能不同。在使用 SystemV 启动脚本的 Linux 系统上,命令如下:

[root@testvm1 ~]# service httpd start
Starting httpd: [Fri Feb 09 08:18:07 2018]          [  OK  ]
[root@testvm1 ~]# service httpd status
httpd (pid  14649) is running...

如果您的主机上有像 Firefox 或 Chrome 这样的浏览器,您可以在浏览器的 URL 行上使用 URL localhost 来显示您的 web 页面,尽管看起来很简单。您还可以使用像 Lynx 这样的文本模式 web 浏览器来查看 web 页面。首先,安装 Lynx (如果它还没有被安装)。

[root@testvm1 ~]# dnf -y install lynx

然后使用下面的命令来显示网页。

[root@testvm1 ~]# lynx localhost

结果在我的终端中是这样的。我已经删除了页面上的很多空白。

  Hello World

<snip>


Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back.
  Arrow keys: Up and Down to move.  Right to follow a link; Left to go back.
 H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list```

接下来,编辑您的 index.html 文件并添加一些 HTML 标记,使其看起来像这样:

<h1>Hello World</h1>

现在刷新浏览器。对于 Lynx,使用组合键 Ctrl + R 。 结果看起来有点不同。如果你的终端支持彩色的话文本是彩色显示的,Lynx 会显示标题,现在它处于居中状态。 在 GUI 浏览器中,文本将以大字体显示。

                                   Hello World

<snip>


Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back.
  Arrow keys: Up and Down to move.  Right to follow a link; Left to go back.
 H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list

后记

从这个小练习中可以看到,建立一个 Apache Web 服务器很容易。 具体情况取决于您的发行版和该发行版提供的 Apache 版本。 在我的环境中,这是一个非常简单的练习。

但不仅仅如此,因为 Apache 非常灵活强大。下个月,我将讨论使用单个 Apache 托管多个网站。


via: https://opensource.com/article/18/2/how-configure-apache-web-server

作者:David Both 译者:amwps290 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

学习怎么在保护 root 密码的安全性的同时,为可信用户赋予所管理的网络功能和特定服务的权限。

我最近写了一个简短的 Bash 程序来将 MP3 文件从一台网络主机的 USB 盘中拷贝到另一台网络主机上去。拷贝出来的文件存放在一台志愿者组织所属服务器的特定目录下,在那里,这些文件可以被下载和播放。

我的程序还会做些其他事情,比如为了自动在网页上根据日期排序,在拷贝文件之前会先对这些文件重命名。在验证拷贝完成后,还会删掉 USB 盘中的所有文件。这个小程序还有一些其他选项,比如 -h 会显示帮助, -t 进入测试模式等等。

我的程序需要以 root 运行才能发挥作用。然而,这个组织中之后很少的人对管理音频和计算机系统有兴趣的,这使得我不得不找那些半吊子的人来,并培训他们登录到用于传输的计算机,运行这个小程序。

倒不是说我不能亲自运行这个程序,但由于外出和疾病等等各种原因, 我不是时常在场的。 即使我在场,作为一名 “懒惰的系统管理员”, 我也希望别人能替我把事情给做了。 因此我写了一些脚本来自动完成这些任务并通过 sudo 来指定某些人来运行这些脚本。 很多 Linux 命令都需要用户以 root 身份来运行。 sudo 能够保护系统免遭一时糊涂造成的意外损坏以及恶意用户的故意破坏。

尽可能的使用 sudo

sudo 是一个很方便的工具,它让我一个具有 root 权限的管理员可以分配所有或者部分管理性的任务给其他用户, 而且还无需告诉他们 root 密码, 从而保证主机的高安全性。

假设,我给了普通用户 ruser 访问我 Bash 程序 myprog 的权限, 而这个程序的部分功能需要 root 权限。 那么该用户可以以 ruser 的身份登录,然后通过以下命令运行 myprog

sudo myprog

sudo 程序会检查 /etc/sudoers 文件,并确认 ruser 是否被许可运行 myprog。如被许可,sudo 会要求该用户输入其密码——而非 root 密码。在 ruser 输入他的密码之后,该程序就运行了。此外,sudo 也记录 myprog 该程序运行的日期和时间、完整的命令,以及谁在运行它。这个数据会记录在 /var/log/security 中。

我发现在培训时记录下每个用 sudo 执行的命令会很有帮助。我可以看到谁执行了哪些命令,他们是否输对了。

我委派了权限给自己和另一个人来运行那一个程序;然而,sudo 可以做更多的事情。 它允许系统管理员委派所管理的网络功能或特定的服务给某个受信的人或某组人。这可以让你在保护了 root 密码的安全性的同时,也赋予了那些功能。

配置 sudoers 文件

作为一名系统管理员,我使用 /etc/sudoers 文件来设置某些用户或某些用户组可以访问某个命令,或某组命令,或所有命令。 这种灵活性是使用 sudo 进行委派时能兼顾功能与简易性的关键。

我一开始对 sudoers 文件感到很困惑,因此下面我会拷贝并分解我所使用主机上的完整 sudoers 文件。 希望在分析的过程中不会让你感到困惑。 我意外地发现, 基于 Red Hat 的发行版中默认的配置文件都会很多注释以及例子来指导你如何做出修改,这使得修改配置文件变得简单了很多,也不需要在互联网上搜索那么多东西了。

不要直接用编辑器来修改 sudoers 文件,而应该用 visudo 命令,因为该命令会在你保存并退出编辑器后就立即生效这些变更。 visudo 也可以使用除了 Vi 之外的其他编辑器。

让我们首先来分析一下文件中的各种别名。

主机别名

主机别名这一节用于创建主机分组,授予该组主机可以访问哪些命令或命令别名。 它的基本思想是,该文件由组织中的所有主机共同维护,然后拷贝到每台主机中的 /etc 中。 其中有些主机, 例如各种服务器, 可以配置成一个组来赋予用户访问特定命令的权限, 比如可以启停类似 HTTPD、DNS 以及网络服务;可以挂载文件系统等等。

在设置主机别名时也可以用 IP 地址替代主机名。

## Host Aliases
## Groups of machines. You may prefer to use hostnames (perhaps using 
## wildcards for entire domains) or IP addresses instead.
# Host_Alias     FILESERVERS = fs1, fs2
# Host_Alias     MAILSERVERS = smtp, smtp2

用户别名

用户别名允许 root 将用户整理成别名组中,并按组来分配特定的 root 权限。在这部分内容中我加了一行 User_Alias AUDIO = dboth, ruser,定义了一个别名 AUDIO 用来指代了两个用户。

正如 sudoers 文件中所阐明的,也可以直接使用 /etc/groups 中定义的组而不用自己设置别名。 如果你定义好的组(假设组名为 audio)已经能满足要求了, 那么在后面分配命令时只需要在组名前加上 % 号,像这样: %audio

## User Aliases
## These aren't often necessary, as you can use regular groups
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname 
## rather than USERALIAS
# User_Alias ADMINS = jsmith, mikem
User_Alias AUDIO = dboth, ruser

命令别名

再后面是命令别名的部分。这些别名表示的是一系列相关的命令, 比如网络相关命令,或者 RPM 包管理命令。 这些别名允许系统管理员方便地为一组命令分配权限。

该部分内容已经设置好了许多别名,这使得分配权限给某类命令变得方便很多。

## Command Aliases
## These are groups of related commands...

## Networking
# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool

## Installation and management of software
# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum

## Services
# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig

## Updating the locate database
# Cmnd_Alias LOCATE = /usr/bin/updatedb

## Storage
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount

## Delegating permissions
# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp 

## Processes
# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall

## Drivers
# Cmnd_Alias DRIVERS = /sbin/modprobe

环境默认值

下面部分内容设置默认的环境变量。这部分最值得关注的是 !visiblepw 这一行, 它表示当用户环境设置成显示密码时禁止 sudo 的运行。 这个安全措施不应该被修改掉。


# Defaults specification

#
# Refuse to run if unable to disable echo on the tty.
#
Defaults   !visiblepw

Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"


Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

命令部分

命令部分是 sudoers 文件的主体。不使用别名并不会影响你完成要实现的效果,别名只是让整个配置工作大幅简化而已。

这部分使用之前定义的别名来告诉 sudo 哪些人可以在哪些机器上执行哪些操作。一旦你理解了这部分内容的语法,你会发现这些例子都非常的直观。 下面我们来看看它的语法。

ruser           ALL=(ALL) ALL 

意即 ruser 可以在任意主机上以任意用户身份运行任意命令

这是一条为用户 ruser 做出的配置。行中第一个 ALL 表示该条规则在所有主机上生效。 第二个 ALL 允许 ruser 以任意其他用户的身份运行命令。 默认情况下, 命令以 root 用户的身份运行, 但 ruser 可以在 sudo 命令行指定程序以其他用户的身份运行。 最后这个 ALL 表示 ruser 可以运行所有命令而不受限制。 这让 ruser 实际上就变成了 root

注意到下面还有一条针对 root 的配置。这允许 root 能通过 sudo 在任何主机上运行任何命令。

root    ALL=(ALL) ALL 

意即 root 可以在任意主机上以任意用户身份运行任意命令

为了实验一下效果,我注释掉了这行, 然后以 root 的身份试着直接运行 chown。 出乎意料的是这样是能成功的。 然后我试了下 sudo chown,结果失败了,提示信息 “Root is not in the sudoers file。 This incident will be reported”。 也就是说 root 可以直接运行任何命令, 但当加上 sudo 时则不行。 这会阻止 root 像其他用户一样使用 sudo 命令来运行其他命令, 但是 root 有太多种方法可以绕过这个约束了。

下面这行是我新增来控制访问 myprog 的。它指定了只有上面定义的 AUDIO 组中的用户才能在 guest1 这台主机上使用 myprog 这个命令。

AUDIO   guest1=/usr/local/bin/myprog

允许 AUDIO 组成员在 guest1 主机上访问 myprog

注意,上面这一行只指定了允许访问的主机名和程序,而没有说用户可以以其他用户的身份来运行该程序。

省略密码

你也可以通过 NOPASSWORD 来让 AUDIO 组中的用户无需密码就能运行 myprog。像这样:

AUDIO   guest1=NOPASSWORD : /usr/local/bin/myprog

允许 AUDIO 组成员在 guest1 主机上不用输入密码即可访问 myprog

我并没有这样做,因为我觉得使用 sudo 的用户必须要停下来想清楚他们正在做的事情,这对他们有好处。 我这里只是举个例子。

wheel

sudoers 文件中命令部分的 wheel 说明(如下所示)允许所有在 wheel 组中的用户在任何机器上运行任何命令。wheel 组在 /etc/group 文件中定义, 用户必须加入该组后才能工作。 组名前面的 % 符号表示 sudo 应该去 /etc/group 文件中查找该组。

%wheel          ALL = (ALL) ALL

运行所有定义在 /etc/group 文件中的 “wheel” 组成员可以在任意主机上运行全部命令

这种方法很好的实现了为多个用户赋予完全的 root 权限而不用提供 root 密码。只需要把该用户加入 wheel 组中就能给他们提供完整的 root 的能力。 它也提供了一种通过 sudo 创建的日志来监控他们行为的途径。 有些 Linux 发行版, 比如 Ubuntu, 会自动将用户的 ID 加入 /etc/group 中的 wheel 组中, 这使得他们能够用 sudo 命令运行所有的特权命令。

结语

我这里只是小试了一把 sudo — 我只是给一到两个用户以 root 权限运行单个命令的权限。完成这些只添加了两行配置(不考虑注释)。 将某项任务的权限委派给其他非 root 用户非常简单,而且可以节省你大量的时间。 同时它还会产生日志来帮你发现问题。

sudoers 文件还有许多其他的配置和能力。查看 sudosudoers 的 man 手册可以深入了解详细信息。


via: https://opensource.com/article/17/12/using-sudo-delegate

作者:David Both 译者:lujun9972 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

 title=")

管理磁盘空间对系统管理员来说是一件重要的日常工作。一旦磁盘空间耗尽就需要进行一系列耗时而又复杂的任务,以提升磁盘分区中可用的磁盘空间。它也需要系统离线才能处理。通常这种任务会涉及到安装一个新的硬盘、引导至恢复模式或者单用户模式、在新硬盘上创建一个分区和一个文件系统、挂载到临时挂载点去从一个太小的文件系统中移动数据到较大的新位置、修改 /etc/fstab 文件的内容来反映出新分区的正确设备名、以及重新引导来重新挂载新的文件系统到正确的挂载点。

我想告诉你的是,当 LVM (逻辑卷管理)首次出现在 Fedora Linux 中时,我是非常抗拒它的。我最初的反应是,我并不需要在我和我的设备之间有这种额外的抽象层。结果是我错了,逻辑卷管理是非常有用的。

LVM 让磁盘空间管理非常灵活。它提供的功能诸如在文件系统已挂载和活动时,很可靠地增加磁盘空间到一个逻辑卷和它的文件系统中,并且,它也允许你将多个物理磁盘和分区融合进一个可以分割成逻辑卷(LV)的单个卷组(VG)中。

卷管理也允许你去减少分配给一个逻辑卷的磁盘空间数量,但是,这里有两个要求,第一,卷必须是未挂载的。第二,在卷空间调整之前,文件系统本身的空间大小必须先被减少。

有一个重要的提示是,文件系统本身必须允许重新调整大小的操作。当重新提升文件系统大小的时候,EXT2、3 和 4 文件系统都允许离线(未挂载状态)或者在线(挂载状态)重新调整大小。你应该去认真了解你打算去调整的文件系统的详细情况,去验证它们是否可以完全调整大小,尤其是否可以在线调整大小。

即时扩展一个文件系统

在我安装一个新的发行版到我的生产用机器中之前,我总是喜欢在一个 VirtualBox 虚拟机中运行这个新的发行版一段时间,以确保它没有任何的致命的问题存在。在几年前的一个早晨,我在我的主要使用的工作站上的虚拟机中安装了一个新发行的 Fedora 版本。我认为我有足够的磁盘空间分配给安装虚拟机的主文件系统。但是,我错了,大约在安装到三分之一时,我耗尽了我的文件系统的空间。幸运的是,VirtualBox 检测到了磁盘空间不足的状态,并且暂停了虚拟机,然后显示了一个明确指出问题所在的错误信息。

请注意,这个问题并不是虚拟机磁盘太小造成的,而是由于宿主机上空间不足,导致虚拟机上的虚拟磁盘在宿主机上的逻辑卷中没有足够的空间去扩展。

因为许多现在的发行版都缺省使用了逻辑卷管理,并且在我的卷组中有一些可用的空余空间,我可以分配额外的磁盘空间到适当的逻辑卷,然后即时扩展宿主机的文件系统。这意味着我不需要去重新格式化整个硬盘,以及重新安装操作系统或者甚至是重启机器。我不过是分配了一些可用空间到适当的逻辑卷中,并且重新调整了文件系统的大小 —— 所有的这些操作都在文件系统在线并且运行着程序的状态下进行的,虚拟机也一直使用着宿主机文件系统。在调整完逻辑卷和文件系统的大小之后,我恢复了虚拟机的运行,并且继续进行安装过程,就像什么问题都没有发生过一样。

虽然这种问题你可能从来也没有遇到过,但是,许多人都遇到过重要程序在运行过程中发生磁盘空间不足的问题。而且,虽然许多程序,尤其是 Windows 程序,并不像 VirtualBox 一样写的很好,且富有弹性,Linux 逻辑卷管理可以使它在不丢失数据的情况下去恢复,也不需要去进行耗时的安装过程。

LVM 结构

逻辑卷管理的磁盘环境结构如下面的图 1 所示。逻辑卷管理允许多个单独的硬盘和/或磁盘分区组合成一个单个的卷组(VG)。卷组然后可以再划分为逻辑卷(LV)或者被用于分配成一个大的单一的卷。普通的文件系统,如 EXT3 或者 EXT4,可以创建在一个逻辑卷上。

在图 1 中,两个完整的物理硬盘和一个第三块硬盘的一个分区组合成一个单个的卷组。在这个卷组中创建了两个逻辑卷和文件系统,比如,可以在每个逻辑卷上创建一个 EXT3 或者 EXT4 的文件系统。

lvm.png

图 1: LVM 允许组合分区和整个硬盘到卷组中

在一个主机上增加磁盘空间是非常简单的,在我的经历中,这种事情是很少的。下面列出了基本的步骤。你也可以创建一个完整的新卷组或者增加新的空间到一个已存在的逻辑卷中,或者创建一个新的逻辑卷。

增加一个新的逻辑卷

有时候需要在主机上增加一个新的逻辑卷。例如,在被提示包含我的 VirtualBox 虚拟机的虚拟磁盘的 /home 文件系统被填满时,我决定去创建一个新的逻辑卷,以存储包含虚拟磁盘在内的虚拟机数据。这将在我的 /home 文件系统中释放大量的空间,并且也允许我去独立地管理虚拟机的磁盘空间。

增加一个新的逻辑卷的基本步骤如下:

  1. 如有需要,安装一个新硬盘。
  2. 可选: 在硬盘上创建一个分区。
  3. 在硬盘上创建一个完整的物理卷(PV)或者一个分区。
  4. 分配新的物理卷到一个已存在的卷组(VG)中,或者创建一个新的卷组。
  5. 从卷空间中创建一个新的逻辑卷(LV)。
  6. 在新的逻辑卷中创建一个文件系统。
  7. /etc/fstab 中增加适当的条目以挂载文件系统。
  8. 挂载文件系统。

为了更详细的介绍,接下来将使用一个示例作为一个实验去教授关于 Linux 文件系统的知识。

示例

这个示例展示了怎么用命令行去扩展一个已存在的卷组,并给它增加更多的空间,在那个空间上创建一个新的逻辑卷,然后在逻辑卷上创建一个文件系统。这个过程一直在运行着和已挂载的文件系统上执行。

警告:仅 EXT3 和 EXT4 文件系统可以在运行和挂载状态下调整大小。许多其它的文件系统,包括 BTRFS 和 ZFS 是不能这样做的。

安装硬盘

如果在系统中现有硬盘上的卷组中没有足够的空间可以增加,那么可能需要去增加一块新的硬盘,然后创建空间增加到逻辑卷中。首先,安装物理硬盘,然后,接着执行后面的步骤。

从硬盘上创建物理卷

首先需要去创建一个新的物理卷(PV)。使用下面的命令,它假设新硬盘已经分配为 /dev/hdd

pvcreate /dev/hdd

在新硬盘上创建一个任意分区并不是必需的。创建的物理卷将被逻辑卷管理器识别为一个新安装的未处理的磁盘或者一个类型为 83 的 Linux 分区。如果你想去使用整个硬盘,创建一个分区并没有什么特别的好处,而且元数据所用的磁盘空间也能用做 PV 的一部分使用。

扩展已存在的卷组

在这个示例中,我将扩展一个已存在的卷组,而不是创建一个新的;你可以选择其它的方式。在物理磁盘已经创建之后,扩展已存在的卷组(VG)去包含新 PV 的空间。在这个示例中,已存在的卷组命名为:MyVG01。

vgextend /dev/MyVG01 /dev/hdd
创建一个逻辑卷

首先,在卷组中从已存在的空余空间中创建逻辑卷。下面的命令创建了一个 50 GB 大小的 LV。这个卷组的名字为 MyVG01,然后,逻辑卷的名字为 Stuff。

lvcreate -L +50G --name Stuff MyVG01
创建文件系统

创建逻辑卷并不会创建文件系统。这个任务必须被单独执行。下面的命令在新创建的逻辑卷中创建了一个 EXT4 文件系统。

mkfs -t ext4 /dev/MyVG01/Stuff
增加一个文件系统卷标

增加一个文件系统卷标,更易于在文件系统以后出现问题时识别它。

e2label /dev/MyVG01/Stuff Stuff
挂载文件系统

在这个时候,你可以创建一个挂载点,并在 /etc/fstab 文件系统中添加合适的条目,以挂载文件系统。

你也可以去检查并校验创建的卷是否正确。你可以使用 dflvsvgs 命令去做这些工作。

在 LVM 文件系统中调整逻辑卷大小

从 Unix 的第一个版本开始,对文件系统的扩展需求就一直伴随,Linux 也不例外。随着有了逻辑卷管理(LVM),现在更加容易了。

  1. 如有需要,安装一个新硬盘。
  2. 可选: 在硬盘上创建一个分区。
  3. 在硬盘上创建一个完整的物理卷(PV)或者一个分区。
  4. 分配新的物理卷到一个已存在的卷组(VG)中,或者创建一个新的卷组。
  5. 从卷空间中创建一个新的逻辑卷(LV),或者用卷组中部分或全部空间扩展已有的逻辑卷。
  6. 如果创建了新的逻辑卷,那么在上面创建一个文件系统。如果对已有的逻辑卷增加空间,使用 resize2fs 命令来增大文件系统来填满逻辑卷。
  7. /etc/fstab 中增加适当的条目以挂载文件系统。
  8. 挂载文件系统。

示例

这个示例展示了怎么用命令行去扩展一个已存在的卷组。它会给 /Staff 文件系统增加大约 50GB 的空间。这将生成一个可用于挂载的文件系统,在 Linux 2.6 内核(及更高)上可即时使用 EXT3 和 EXT4 文件系统。我不推荐你用于任何关键系统,但是这是可行的,我已经成功了好多次;即使是在根(/)文件系统上。是否使用自己把握风险。

警告:仅 EXT3 和 EXT4 文件系统可以在运行和挂载状态下调整大小。许多其它的文件系统,包括 BTRFS 和 ZFS 是不能这样做的。

安装硬盘

如果在系统中现有硬盘上的卷组中没有足够的空间可以增加,那么可能需要去增加一块新的硬盘,然后创建空间增加到逻辑卷中。首先,安装物理硬盘,然后,接着执行后面的步骤。

从硬盘上创建物理卷

首先需要去创建一个新的物理卷(PV)。使用下面的命令,它假设新硬盘已经分配为 /dev/hdd

pvcreate /dev/hdd

在新硬盘上创建一个任意分区并不是必需的。创建的物理卷将被逻辑卷管理器识别为一个新安装的未处理的磁盘或者一个类型为 83 的 Linux 分区。如果你想去使用整个硬盘,创建一个分区并没有什么特别的好处,而且元数据所用的磁盘空间也能用做 PV 的一部分使用。

增加物理卷到已存在的卷组

在这个示例中,我将使用一个新的物理卷来扩展一个已存在的卷组。在物理卷已经创建之后,扩展已存在的卷组(VG)去包含新 PV 的空间。在这个示例中,已存在的卷组命名为:MyVG01。

vgextend /dev/MyVG01 /dev/hdd
扩展逻辑卷

首先,在卷组中从已存在的空余空间中创建逻辑卷。下面的命令创建了一个 50 GB 大小的 LV。这个卷组的名字为 MyVG01,然后,逻辑卷的名字为 Stuff。

lvcreate -L +50G --name Stuff MyVG01
扩展文件系统

如果你使用了 -r 选项,扩展逻辑卷也将扩展器文件系统。如果你不使用 -r 选项,该操作不行单独执行。下面的命令在新调整大小的逻辑卷中调整了文件系统大小。

resize2fs /dev/MyVG01/Stuff

你也可以去检查并校验调整大小的卷是否正确。你可以使用 dflvsvgs 命令去做这些工作。

提示

过去几年来,我学习了怎么去做让逻辑卷管理更加容易的一些知识,希望这些提示对你有价值。

  • 除非你有一个明确的原因去使用其它的文件系统外,推荐使用可扩展的文件系统。除了 EXT2、3、和 4 外,并不是所有的文件系统都支持调整大小。EXT 文件系统不但速度快,而且它很高效。在任何情况下,如果默认的参数不能满足你的需要,它们(指的是文件系统参数)可以通过一位知识丰富的系统管理员来调优它。
  • 使用有意义的卷和卷组名字。
  • 使用 EXT 文件系统标签

我知道,像我一样,大多数的系统管理员都抗拒逻辑卷管理。我希望这篇文章能够鼓励你至少去尝试一个 LVM。如果你能那样做,我很高兴;因为,自从我使用它之后,我的硬盘管理任务变得如此的简单。

关于作者

David Both 是一位 Linux 和开源软件的倡导者,住在 Raleigh, North Carolina。他在 IT 行业工作了 40 多年,在 IBM 工作了 20 多年。在 IBM 期间,他在 1981 年为最初的 IBM PC 编写了第一个培训课程。他曾教授红帽的 RHCE 课程,并在 MCI Worldcom、Cisco和 North Carolina 工作。他已经使用 Linux 和开源软件工作了将近 20 年。


via: https://opensource.com/business/16/9/linux-users-guide-lvm

作者:David Both 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

学习如何使用链接,通过从 Linux 文件系统多个位置来访问文件,可以让日常工作变得轻松。

 title=

在我为 opensource.com 写过的关于 Linux 文件系统方方面面的文章中,包括 Linux 的 EXT4 文件系统的历史、特性以及最佳实践在 Linux 中管理设备Linux 文件系统概览用户指南:逻辑卷管理,我曾简要的提到过 Linux 文件系统一个有趣的特性,它允许用户从多个位置来访问 Linux 文件目录树中的文件来简化一些任务。

Linux 文件系统中有两种 链接 link 硬链接 hard link 软链接 soft link 。虽然二者差别显著,但都用来解决相似的问题。它们都提供了对单个文件的多个目录项(引用)的访问,但实现却大为不同。链接的强大功能赋予了 Linux 文件系统灵活性,因为一切皆是文件

举个例子,我曾发现一些程序要求特定的版本库方可运行。 当用升级后的库替代旧库后,程序会崩溃,提示旧版本库缺失。通常,库名的唯一变化就是版本号。出于直觉,我仅仅给程序添加了一个新的库链接,并以旧库名称命名。我试着再次启动程序,运行良好。程序就是一个游戏,人人都明白,每个玩家都会尽力使游戏进行下去。

事实上,几乎所有的应用程序链接库都使用通用的命名规则,链接名称中包含了主版本号,链接所指向的文件的文件名中同样包含了小版本号。再比如,程序的一些必需文件为了迎合 Linux 文件系统规范,从一个目录移动到另一个目录中,系统为了向后兼容那些不能获取这些文件新位置的程序在旧的目录中存放了这些文件的链接。如果你对 /lib64 目录做一个长清单列表,你会发现很多这样的例子。

lrwxrwxrwx.  1 root root       36 Dec  8  2016 cracklib_dict.hwm -> ../../usr/share/cracklib/pw_dict.hwm 
lrwxrwxrwx.  1 root root       36 Dec  8  2016 cracklib_dict.pwd -> ../../usr/share/cracklib/pw_dict.pwd 
lrwxrwxrwx.  1 root root       36 Dec  8  2016 cracklib_dict.pwi -> ../../usr/share/cracklib/pw_dict.pwi
lrwxrwxrwx.  1 root root       27 Jun  9  2016 libaccountsservice.so.0 -> libaccountsservice.so.0.0.0 
-rwxr-xr-x.  1 root root   288456 Jun  9  2016 libaccountsservice.so.0.0.0 
lrwxrwxrwx   1 root root       15 May 17 11:47 libacl.so.1 -> libacl.so.1.1.0 
-rwxr-xr-x   1 root root    36472 May 17 11:47 libacl.so.1.1.0 
lrwxrwxrwx.  1 root root       15 Feb  4  2016 libaio.so.1 -> libaio.so.1.0.1 
-rwxr-xr-x.  1 root root     6224 Feb  4  2016 libaio.so.1.0.0 
-rwxr-xr-x.  1 root root     6224 Feb  4  2016 libaio.so.1.0.1 
lrwxrwxrwx.  1 root root       30 Jan 16 16:39 libakonadi-calendar.so.4 -> libakonadi-calendar.so.4.14.26 
-rwxr-xr-x.  1 root root   816160 Jan 16 16:39 libakonadi-calendar.so.4.14.26 
lrwxrwxrwx.  1 root root       29 Jan 16 16:39 libakonadi-contact.so.4 -> libakonadi-contact.so.4.14.26 

/lib64 目录下的一些链接

在上面展示的 /lib64 目录清单列表中,文件模式第一个字母 l (小写字母 l)表示这是一个软链接(又称符号链接)。

硬链接

Linux 的 EXT4 文件系统的历史、特性以及最佳实践一文中,我曾探讨过这样一个事实,每个文件都有一个包含该文件信息的 inode,包含了该文件的位置信息。上述文章中的图2展示了一个指向 inode 的单一目录项。每个文件都至少有一个目录项指向描述该文件信息的 inode ,目录项是一个硬链接,因此每个文件至少都有一个硬链接。

如下图 1 所示,多个目录项指向了同一 inode 。这些目录项都是硬链接。我曾在三个目录项中使用波浪线 (~) 的缩写,这是用户目录的惯例表示,因此在该例中波浪线等同于 /home/user 。值得注意的是,第四个目录项是一个完全不同的目录,/home/shared,可能是该计算机上用户的共享文件目录。

fig1directory_entries.png

图 1

硬链接被限制在一个单一的文件系统中。此处的“文件系统” 是指挂载在特定挂载点上的分区或逻辑卷,此例中是 /home。这是因为在每个文件系统中的 inode 号都是唯一的。而在不同的文件系统中,如 /var/opt,会有和 /home 中相同的 inode 号。

因为所有的硬链接都指向了包含文件元信息的单一 inode ,这些属性都是文件的一部分,像所属关系、权限、到该 inode 的硬链接数目,对每个硬链接来说这些特性没有什么不同的。这是一个文件所具有的一组属性。唯一能区分这些文件的是包含在 inode 信息中的文件名。链接到同一目录中的单一文件/ inode 的硬链接必须拥有不同的文件名,这是基于同一目录下不能存在重复的文件名的事实的。

文件的硬链接数目可通过 ls -l 来查看,如果你想查看实际节点号,可使用 ls -li 命令。

符号(软)链接

硬链接和软链接(也称为 符号链接 symlink )的区别在于,硬链接直接指向属于该文件的 inode ,而软链接直接指向一个目录项,即指向一个硬链接。因为软链接指向的是一个文件的硬链接而非该文件的 inode ,所以它们并不依赖于 inode 号,这使得它们能跨越不同的文件系统、分区和逻辑卷起作用。

软链接的缺点是,一旦它所指向的硬链接被删除或重命名后,该软链接就失效了。软链接虽然还在,但所指向的硬链接已不存在。所幸的是,ls 命令能以红底白字的方式在其列表中高亮显示失效的软链接。

实验项目: 链接实验

我认为最容易理解链接用法及其差异的方法是动手搭建一个项目。这个项目应以非超级用户的身份在一个空目录下进行。我创建了 ~/temp 目录做这个实验,你也可以这么做。这么做可为项目创建一个安全的环境且提供一个新的空目录让程序运作,如此以来这儿仅存放和程序有关的文件。

初始工作

首先,在你要进行实验的目录下为该项目中的任务创建一个临时目录,确保当前工作目录(PWD)是你的主目录,然后键入下列命令。

mkdir temp

使用这个命令将当前工作目录切换到 ~/temp

cd temp

实验开始,我们需要创建一个能够链接到的文件,下列命令可完成该工作并向其填充内容。

du -h > main.file.txt

使用 ls -l 长列表命名确认文件正确地创建了。运行结果应类似于我的。注意文件大小只有 7 字节,但你的可能会有 1~2 字节的变动。

[dboth@david temp]$ ls -l 
total 4 
-rw-rw-r-- 1 dboth dboth 7 Jun 13 07:34 main.file.txt

在列表中,文件模式串后的数字 1 代表存在于该文件上的硬链接数。现在应该是 1 ,因为我们还没有为这个测试文件建立任何硬链接。

对硬链接进行实验

硬链接创建一个指向同一 inode 的新目录项,当为文件添加一个硬链接时,你会看到链接数目的增加。确保当前工作目录仍为 ~/temp。创建一个指向 main.file.txt 的硬链接,然后查看该目录下文件列表。

[dboth@david temp]$ ln main.file.txt link1.file.txt 
[dboth@david temp]$ ls -l 
total 8 
-rw-rw-r-- 2 dboth dboth 7 Jun 13 07:34 link1.file.txt 
-rw-rw-r-- 2 dboth dboth 7 Jun 13 07:34 main.file.txt

目录中两个文件都有两个链接且大小相同,时间戳也一样。这就是有一个 inode 和两个硬链接(即该文件的目录项)的一个文件。再建立一个该文件的硬链接,并列出目录清单内容。你可以建立硬链接: link1.file.txtmain.file.txt

[dboth@david temp]$ ln link1.file.txt link2.file.txt ; ls -l
total 16 
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 link1.file.txt 
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 link2.file.txt 
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 main.file.txt

注意,该目录下的每个硬链接必须使用不同的名称,因为同一目录下的两个文件不能拥有相同的文件名。试着创建一个和现存链接名称相同的硬链接。

[dboth@david temp]$ ln main.file.txt link2.file.txt 
ln: failed to create hard link 'link2.file.txt': File exists

显然不行,因为 link2.file.txt 已经存在。目前为止我们只在同一目录下创建硬链接,接着在临时目录的父目录(你的主目录)中创建一个链接。

[dboth@david temp]$ ln main.file.txt ../main.file.txt ; ls -l ../main*
-rw-rw-r--    4 dboth dboth     7 Jun 13 07:34 main.file.txt

上面的 ls 命令显示 main.file.txt 文件确实存在于主目录中,且与该文件在 temp 目录中的名称一致。当然它们不是不同的文件,它们是同一文件的两个链接,指向了同一文件的目录项。为了帮助说明下一点,在 temp 目录中添加一个非链接文件。

[dboth@david temp]$ touch unlinked.file ; ls -l
total 12
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link1.file.txt
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link2.file.txt
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
-rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file

使用 ls 命令的 i 选项查看 inode 的硬链接号和新创建文件的硬链接号。

[dboth@david temp]$ ls -li
total 12
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link1.file.txt
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link2.file.txt
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file

注意上面文件模式左边的数字 657024 ,这是三个硬链接文件所指的同一文件的 inode 号,你也可以使用 i 选项查看主目录中所创建的链接的节点号,和该值相同。而那个只有一个链接的 inode 号和其他的不同,在你的系统上看到的 inode 号或许不同于本文中的。

接着改变其中一个硬链接文件的大小。

[dboth@david temp]$ df -h > link2.file.txt ; ls -li
total 12
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link1.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link2.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 main.file.txt
657863 -rw-rw-r-- 1 dboth dboth    0 Jun 14 08:18 unlinked.file

现在所有的硬链接文件大小都比原来大了,因为多个目录项都链接着同一文件。

下个实验在我的电脑上会出现这样的结果,是因为我的 /tmp 目录在一个独立的逻辑卷上。如果你有单独的逻辑卷或文件系统在不同的分区上(如果未使用逻辑卷),确定你是否能访问那个分区或逻辑卷,如果不能,你可以在电脑上挂载一个 U 盘,如果上述方式适合你,你可以进行这个实验。

试着在 /tmp 目录中建立一个 ~/temp 目录下文件的链接(或你的文件系统所在的位置)。

[dboth@david temp]$ ln link2.file.txt /tmp/link3.file.txt
ln: failed to create hard link '/tmp/link3.file.txt' => 'link2.file.txt': 
Invalid cross-device link

为什么会出现这个错误呢? 原因是每一个单独的可挂载文件系统都有一套自己的 inode 号。简单的通过 inode 号来跨越整个 Linux 文件系统结构引用一个文件会使系统困惑,因为相同的节点号会存在于每个已挂载的文件系统中。

有时你可能会想找到一个 inode 的所有硬链接。你可以使用 ls -li 命令。然后使用 find 命令找到所有硬链接的节点号。

[dboth@david temp]$ find . -inum 657024 
./main.file.txt
./link1.file.txt
./link2.file.txt

注意 find 命令不能找到所属该节点的四个硬链接,因为我们在 ~/temp 目录中查找。 find 命令仅在当前工作目录及其子目录中查找文件。要找到所有的硬链接,我们可以使用下列命令,指定你的主目录作为起始查找条件。

[dboth@david temp]$ find ~ -samefile main.file.txt 
/home/dboth/temp/main.file.txt
/home/dboth/temp/link1.file.txt
/home/dboth/temp/link2.file.txt
/home/dboth/main.file.txt

如果你是非超级用户,没有权限,可能会看到错误信息。这个命令也使用了 -samefile 选项而不是指定文件的节点号。这个效果和使用 inode 号一样且更容易,如果你知道其中一个硬链接名称的话。

对软链接进行实验

如你刚才看到的,不能跨越文件系统边界创建硬链接,即在逻辑卷或文件系统中从一个文件系统到另一个文件系统。软链接给出了这个问题的解决方案。虽然它们可以达到相同的目的,但它们是非常不同的,知道这些差异是很重要的。

让我们在 ~/temp 目录中创建一个符号链接来开始我们的探索。

[dboth@david temp]$ ln -s link2.file.txt link3.file.txt ; ls -li
total 12
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link1.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link2.file.txt
658270 lrwxrwxrwx 1 dboth dboth   14 Jun 14 15:21 link3.file.txt -> 
link2.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 main.file.txt
657863 -rw-rw-r-- 1 dboth dboth    0 Jun 14 08:18 unlinked.file

拥有节点号 657024 的那些硬链接没有变化,且硬链接的数目也没有变化。新创建的符号链接有不同的 inode 号 658270。 名为 link3.file.txt 的软链接指向了 link2.file.txt 文件。使用 cat 命令查看 link3.file.txt 文件的内容。符号链接的 inode 信息以字母 l (小写字母 l)开头,意味着这个文件实际是个符号链接。

上例中软链接文件 link3.file.txt 的大小只有 14 字节。这是文本内容 link3.file.txt 的大小,即该目录项的实际内容。目录项 link3.file.txt 并不指向一个 inode ;它指向了另一个目录项,这在跨越文件系统建立链接时很有帮助。现在试着创建一个软链接,之前在 /tmp 目录中尝试过的。

[dboth@david temp]$ ln -s /home/dboth/temp/link2.file.txt 
/tmp/link3.file.txt ; ls -l /tmp/link*
lrwxrwxrwx 1 dboth dboth 31 Jun 14 21:53 /tmp/link3.file.txt -> 
/home/dboth/temp/link2.file.txt

删除链接

当你删除硬链接或硬链接所指的文件时,需要考虑一些问题。

首先,让我们删除硬链接文件 main.file.txt。注意指向 inode 的每个目录项就是一个硬链接。

[dboth@david temp]$ rm main.file.txt ; ls -li
total 8
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link1.file.txt
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link2.file.txt
658270 lrwxrwxrwx 1 dboth dboth   14 Jun 14 15:21 link3.file.txt -> 
link2.file.txt
657863 -rw-rw-r-- 1 dboth dboth    0 Jun 14 08:18 unlinked.file

main.file.txt 是该文件被创建时所创建的第一个硬链接。现在删除它,仍然保留着原始文件和硬盘上的数据以及所有剩余的硬链接。要删除原始文件,你必须删除它的所有硬链接。

现在删除 link2.file.txt 硬链接文件。

[dboth@david temp]$ rm link2.file.txt ; ls -li 
total 8 
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link1.file.txt 
658270 lrwxrwxrwx 1 dboth dboth   14 Jun 14 15:21 link3.file.txt -> 
link2.file.txt 
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 main.file.txt 
657863 -rw-rw-r-- 1 dboth dboth    0 Jun 14 08:18 unlinked.file

注意软链接的变化。删除软链接所指的硬链接会使该软链接失效。在我的系统中,断开的链接用颜色高亮显示,目标的硬链接会闪烁显示。如果需要修复这个损坏的软链接,你需要在同一目录下建立一个和旧链接相同名字的硬链接,只要不是所有硬链接都已删除就行。您还可以重新创建链接本身,链接保持相同的名称,但指向剩余的硬链接中的一个。当然如果软链接不再需要,可以使用 rm 命令删除它们。

unlink 命令在删除文件和链接时也有用。它非常简单且没有选项,就像 rm 命令一样。然而,它更准确地反映了删除的基本过程,因为它删除了目录项与被删除文件的链接。

写在最后

我用过这两种类型的链接很长一段时间后,我开始了解它们的能力和特质。我为我所教的 Linux 课程编写了一个实验室项目,以充分理解链接是如何工作的,并且我希望增进你的理解。

(题图: Paul Lewin,Opensource.com 修改。 CC BY-SA 2.0


作者简介:

戴维.布斯 - 戴维.布斯是 Linux 和开源倡导者,居住在北卡罗莱纳的罗列 。他在 IT 行业工作了四十年,为 IBM 工作了 20 多年的 OS/2。在 IBM 时,他在 1981 年编写了最初的 IBM PC 的第一个培训课程。他为 RedHat 教授过 RHCE 班,并曾在 MCI Worldcom、思科和北卡罗莱纳州工作。他已经用 Linux 和开源软件工作将近 20 年了。


via: https://opensource.com/article/17/6/linking-linux-filesystem

作者:David Both 译者:yongshouzhang 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

没有时间运行命令?使用 cron 的计划任务意味着你不用熬夜程序也可以运行。

系统管理员(在许多好处中)的挑战之一是在你该睡觉的时候去运行一些任务。例如,一些任务(包括定期循环运行的任务)需要在没有人使用计算机资源的时候去运行,如午夜或周末。在下班后,我没有时间去运行命令或脚本。而且,我也不想在晚上去启动备份或重大更新。

取而代之的是,我使用两个服务功能在我预定的时间去运行命令、程序和任务。cron 和 at 服务允许系统管理员去安排任务运行在未来的某个特定时间。at 服务指定在某个时间去运行一次任务。cron 服务可以安排任务在一个周期上重复,比如天、周、或月。

在这篇文章中,我将介绍 cron 服务和怎么去使用它。

常见(和非常见)的 cron 用途

我使用 cron 服务去安排一些常见的事情,比如,每天凌晨 2:00 发生的定期备份,我也使用它去做一些不常见的事情。

  • 许多电脑上的系统时钟(比如,操作系统时间)都设置为使用网络时间协议(NTP)。 NTP 设置系统时间后,它不会去设置硬件时钟,它可能会“漂移”。我使用 cron 基于系统时间去设置硬件时钟。
  • 我还有一个 Bash 程序,我在每天早晨运行它,去在每台电脑上创建一个新的 “每日信息” (MOTD)。它包含的信息有当前的磁盘使用情况等有用的信息。
  • 许多系统进程和服务,像 Logwatchlogrotate、和 Rootkit Hunter,使用 cron 服务去安排任务和每天运行程序。

crond 守护进程是一个完成 cron 功能的后台服务。

cron 服务检查在 /var/spool/cron/etc/cron.d 目录中的文件,以及 /etc/anacrontab 文件。这些文件的内容定义了以不同的时间间隔运行的 cron 作业。个体用户的 cron 文件是位于 /var/spool/cron,而系统服务和应用生成的 cron 作业文件放在 /etc/cron.d 目录中。/etc/anacrontab 是一个特殊的情况,它将在本文中稍后部分介绍。

使用 crontab

cron 实用程序运行基于一个 cron 表(crontab)中指定的命令。每个用户,包括 root,都有一个 cron 文件。这些文件缺省是不存在的。但可以使用 crontab -e 命令创建在 /var/spool/cron 目录中,也可以使用该命令去编辑一个 cron 文件(看下面的脚本)。我强烈建议你,不要使用标准的编辑器(比如,Vi、Vim、Emacs、Nano、或者任何其它可用的编辑器)。使用 crontab 命令不仅允许你去编辑命令,也可以在你保存并退出编辑器时,重启动 crond 守护进程。crontab 命令使用 Vi 作为它的底层编辑器,因为 Vi 是预装的(至少在大多数的基本安装中是预装的)。

现在,cron 文件是空的,所以必须从头添加命令。 我增加下面示例中定义的作业到我的 cron 文件中,这是一个快速指南,以便我知道命令中的各个部分的意思是什么,你可以自由拷贝它,供你自己使用。

# crontab -e
SHELL=/bin/bash
[email protected]
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

# backup using the rsbu program to the internal 4TB HDD and then 4TB external
01 01 * * * /usr/local/bin/rsbu -vbd1 ; /usr/local/bin/rsbu -vbd2

# Set the hardware clock to keep it in sync with the more accurate system clock
03 05 * * * /sbin/hwclock --systohc

# Perform monthly updates on the first of the month
# 25 04 1 * * /usr/bin/dnf -y update

crontab 命令用于查看或编辑 cron 文件。

上面代码中的前三行设置了一个缺省环境。对于给定用户,环境变量必须是设置的,因为,cron 不提供任何方式的环境。SHELL 变量指定命令运行使用的 shell。这个示例中,指定为 Bash shell。MAILTO 变量设置发送 cron 作业结果的电子邮件地址。这些电子邮件提供了 cron 作业(备份、更新、等等)的状态,和你从命令行中手动运行程序时看到的结果是一样的。第三行为环境设置了 PATH 变量。但即使在这里设置了路径,我总是使用每个程序的完全限定路径。

在上面的示例中有几个注释行,它详细说明了定义一个 cron 作业所要求的语法。我将在下面分别讲解这些命令,然后,增加更多的 crontab 文件的高级特性。

01 01 * * * /usr/local/bin/rsbu -vbd1 ; /usr/local/bin/rsbu -vbd2

在我的 /etc/crontab 中的这一行运行一个脚本,用于为我的系统执行备份。

这一行运行我自己编写的 Bash shell 脚本 rsbu,它对我的系统做完全备份。这个作业每天的凌晨 1:01 (01 01) 运行。在这三、四、五位置上的星号(*),像文件通配符一样代表一个特定的时间,它们代表 “一个月中的每天”、“每个月” 和 “一周中的每天”,这一行会运行我的备份两次,一次备份内部专用的硬盘驱动器,另外一次运行是备份外部的 USB 驱动器,使用它这样我可以很保险。

接下来的行我设置了一个硬件时钟,它使用当前系统时钟作为源去设置硬件时钟。这一行设置为每天凌晨 5:03 分运行。

03 05 * * * /sbin/hwclock --systohc

这一行使用系统时间作为源来设置硬件时钟。

我使用的第三个也是最后一个的 cron 作业是去执行一个 dnfyum 更新,它在每个月的第一天的凌晨 04:25 运行,但是,我注释掉了它,以后不再运行。

# 25 04 1 * * /usr/bin/dnf -y update

这一行用于执行一个每月更新,但是,我也把它注释掉了。

其它的定时任务技巧

现在,让我们去做一些比基本知识更有趣的事情。假设你希望在每周四下午 3:00 去运行一个特别的作业:

00 15 * * Thu /usr/local/bin/mycronjob.sh

这一行会在每周四下午 3:00 运行 mycronjob.sh 这个脚本。

或者,或许你需要在每个季度末去运行一个季度报告。cron 服务没有为 “每个月的最后一天” 设置选项,因此,替代方式是使用下一个月的第一天,像如下所示(这里假设当作业准备运行时,报告所需要的数据已经准备好了)。

02 03 1 1,4,7,10 * /usr/local/bin/reports.sh

在季度末的下一个月的第一天运行这个 cron 作业。

下面展示的这个作业,在每天的上午 9:01 到下午 5:01 之间,每小时运行一次。

01 09-17 * * * /usr/local/bin/hourlyreminder.sh

有时,你希望作业在业务期间定时运行。

我遇到一个情况,需要作业在每二、三或四小时去运行。它需要用期望的间隔去划分小时,比如, */3 为每三个小时,或者 6-18/3 为上午 6 点到下午 6 点每三个小时运行一次。其它的时间间隔的划分也是类似的。例如,在分钟位置的表达式 */15 意思是 “每 15 分钟运行一次作业”。

*/5 08-18/2 * * * /usr/local/bin/mycronjob.sh

这个 cron 作业在上午 8:00 到下午 18:59 之间,每五分钟运行一次作业。

需要注意的一件事情是:除法表达式的结果必须是余数为 0(即整除)。换句话说,在这个例子中,这个作业被设置为在上午 8 点到下午 6 点之间的偶数小时每 5 分钟运行一次(08:00、08:05、 08:10、 08:15……18:55 等等),而不运行在奇数小时。另外,这个作业不能运行在下午 7:00 到上午 7:59 之间。(LCTT 译注:此处本文表述有误,根据正确情况修改)

我相信,你可以根据这些例子想到许多其它的可能性。

限制访问 cron

普通用户使用 cron 访问可能会犯错误,例如,可能导致系统资源(比如内存和 CPU 时间)被耗尽。为避免这种可能的问题, 系统管理员可以通过创建一个 /etc/cron.allow 文件去限制用户访问,它包含了一个允许去创建 cron 作业的用户列表。(不管是否列在这个列表中,)不能阻止 root 用户使用 cron。

通过阻止非 root 用户创建他们自己的 cron 作业,那也许需要将非 root 用户的 cron 作业添加到 root 的 crontab 中, “但是,等等!” 你说,“不是以 root 去运行这些作业?” 不一定。在这篇文章中的第一个示例中,出现在注释中的用户名字段可以用于去指定一个运行作业的用户 ID。这可以防止特定的非 root 用户的作业以 root 身份去运行。下面的示例展示了一个作业定义,它以 “student” 用户去运行这个作业:

04 07 * * * student /usr/local/bin/mycronjob.sh

如果没有指定用户,这个作业将以 contab 文件的所有者用户去运行,在这个情况中是 root。

cron.d

目录 /etc/cron.d 中是一些应用程序,比如 SpamAssassinsysstat 安装的 cron 文件。因为,这里没有 spamassassin 或者 sysstat 用户,这些程序需要一个位置去放置 cron 文件,因此,它们被放在 /etc/cron.d 中。

下面的 /etc/cron.d/sysstat 文件包含系统活动报告(SAR)相关的 cron 作业。这些 cron 文件和用户 cron 文件格式相同。

# Run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 1 1
# Generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib64/sa/sa2 -A

sysstat 包安装了 /etc/cron.d/sysstat cron 文件来运行程序生成 SAR。

该 sysstat cron 文件有两行执行任务。第一行每十分钟去运行 sa1 程序去收集数据,存储在 /var/log/sa 目录中的一个指定的二进制文件中。然后,在每天晚上的 23:53, sa2 程序运行来创建一个每日汇总。

计划小贴士

我在 crontab 文件中设置的有些时间看上起似乎是随机的,在某种程度上说,确实是这样的。尝试去安排 cron 作业可能是件很具有挑战性的事, 尤其是作业的数量越来越多时。我通常在我的每个电脑上仅有一些任务,它比起我工作用的那些生产和实验环境中的电脑简单多了。

我管理的一个系统有 12 个每天晚上都运行 cron 作业,另外 3、4 个在周末或月初运行。那真是个挑战,因为,如果有太多作业在同一时间运行,尤其是备份和编译系统,会耗尽内存并且几乎填满交换文件空间,这会导致系统性能下降甚至是超负荷,最终什么事情都完不成。我增加了一些内存并改进了如何计划任务。我还删除了一些写的很糟糕、使用大量内存的任务。

crond 服务假设主机计算机 24 小时运行。那意味着如果在一个计划运行的期间关闭计算机,这些计划的任务将不再运行,直到它们计划的下一次运行时间。如果这里有关键的 cron 作业,这可能导致出现问题。 幸运的是,在定期运行的作业上,还有一个其它的选择: anacron

anacron

anacron 程序执行和 cron 一样的功能,但是它增加了运行被跳过的作业的能力,比如,如果计算机已经关闭或者其它的原因导致无法在一个或多个周期中运行作业。它对笔记本电脑或其它被关闭或进行睡眠模式的电脑来说是非常有用的。

只要电脑一打开并引导成功,anacron 会检查过去是否有计划的作业被错过。如果有,这些作业将立即运行,但是,仅运行一次(而不管它错过了多少次循环运行)。例如,如果一个每周运行的作业在最近三周因为休假而系统关闭都没有运行,它将在你的电脑一启动就立即运行,但是,它仅运行一次,而不是三次。

anacron 程序提供了一些对周期性计划任务很好用的选项。它是安装在你的 /etc/cron.[hourly|daily|weekly|monthly] 目录下的脚本。 根据它们需要的频率去运行。

它是怎么工作的呢?接下来的这些要比前面的简单一些。

1、 crond 服务运行在 /etc/cron.d/0hourly 中指定的 cron 作业。

# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly

/etc/cron.d/0hourly 中的内容使位于 /etc/cron.hourly 中的 shell 脚本运行。

2、 在 /etc/cron.d/0hourly 中指定的 cron 作业每小时运行一次 run-parts 程序。

3、 run-parts 程序运行所有的在 /etc/cron.hourly 目录中的脚本。

4、 /etc/cron.hourly 目录包含的 0anacron 脚本,它使用如下的 /etdc/anacrontab 配置文件去运行 anacron 程序。

# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22

#period in days   delay in minutes   job-identifier   command
1       5       cron.daily              nice run-parts /etc/cron.daily
7       25      cron.weekly             nice run-parts /etc/cron.weekly
@monthly 45     cron.monthly            nice run-parts /etc/cron.monthly

/etc/anacrontab 文件中的内容在合适的时间运行在 cron.[daily|weekly|monthly] 目录中的可执行文件。

5、 anacron 程序每日运行一次位于 /etc/cron.daily 中的作业。它每周运行一次位于 /etc/cron.weekly 中的作业。以及每月运行一次 cron.monthly 中的作业。注意,在每一行指定的延迟时间,它可以帮助避免这些作业与其它 cron 作业重叠。

我在 /usr/local/bin 目录中放置它们,而不是在 cron.X 目录中放置完整的 Bash 程序,这会使我从命令行中运行它们更容易。然后,我在 cron 目录中增加一个符号连接,比如,/etc/cron.daily

anacron 程序不是设计用于在指定时间运行程序的。而是,用于在一个指定的时间开始,以一定的时间间隔去运行程序,比如,从每天的凌晨 3:00(看上面脚本中的 START_HOURS_RANGE 行)、从周日(每周第一天)和这个月的第一天。如果任何一个或多个循环错过,anacron 将立即运行这个错过的作业。

更多的关于设置限制

我在我的计算机上使用了很多运行计划任务的方法。所有的这些任务都需要一个 root 权限去运行。在我的经验中,很少有普通用户去需要运行 cron 任务,一种情况是开发人员需要一个 cron 作业去启动一个开发实验室的每日编译。

限制非 root 用户去访问 cron 功能是非常重要的。然而,在一些特殊情况下,用户需要去设置一个任务在预先指定时间运行,而 cron 可以允许他们去那样做。许多用户不理解如何正确地配置 cron 去完成任务,并且他们会出错。这些错误可能是无害的,但是,往往不是这样的,它们可能导致问题。通过设置功能策略,使用户与管理员互相配合,可以使个别的 cron 作业尽可能地不干扰其它的用户和系统功能。

可以给为单个用户或组分配的资源设置限制,但是,这是下一篇文章中的内容。

更多信息,在 croncrontabanacronanacrontab、和 run-parts 的 man 页面上,所有的这些信息都描述了 cron 系统是如何工作的。


作者简介:

David Both - 是一位 Linux 和开源软件的倡导者,居住在 Raleigh,North Carolina。他从事 IT 行业超过四十年,并且在 IBM 教授 OS/2 超过 20 年时间,他在 1981 年 IBM 期间,为最初的 IBM PC 写了第一部培训教程。他为 Red Hat 教授 RHCE 系列课程,并且他也为 MCI Worldcom、 Cisco、和 North Carolina 州工作。他使用 Linux 和开源软件工作差不多 20 年了。


via: https://opensource.com/article/17/11/how-use-cron-linux

作者:David Both 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

本文旨在高屋建瓴地来讨论 Linux 文件系统概念,而不是对某种特定的文件系统,比如 EXT4 是如何工作的进行具体的描述。另外,本文也不是一个文件系统命令的教程。

每台通用计算机都需要将各种数据存储在硬盘驱动器(HDD)或其他类似设备上,比如 USB 存储器。这样做有两个原因。首先,当计算机关闭以后,内存(RAM)会失去存于它里面的内容。尽管存在非易失类型的 RAM,在计算机断电以后还能把数据存储下来(比如采用 USB 闪存和固态硬盘的闪存),但是,闪存和标准的、易失性的 RAM,比如 DDR3 以及其他相似类型的 RAM 相比,要贵很多。

数据需要存储在硬盘驱动上的另一个原因是,即使是标准的 RAM 也要比普通硬盘贵得多。尽管 RAM 和硬盘的价格都在迅速下降,但是 RAM 的价格依旧在以字节为单位来计算。让我们进行一个以字节为单位的快速计算:基于 16 GB 大的 RAM 的价格和 2 TB 大的硬盘驱动的价格。计算显示 RAM 的价格大约比硬盘驱动贵 71 倍。今天,一个典型的 RAM 的价格大约是 0.000000004373750 美元/每字节。

直观的展示一下在很久以前 RAM 的价格,在计算机发展的非常早的时期,其中一种类型的 RAM 是基于在 CRT 屏幕上的点。这种 RAM 非常昂贵,大约 1 美元/每字节。

定义

你可能听过其他人以各种不同和令人迷惑的方式谈论过文件系统。文件系统这个单词本身有多重含义,你需要从一个讨论或文件的上下文中理解它的正确含义。

我将根据我所观察到的在不同情况下使用“文件系统”这个词来定义它的不同含义。注意,尽管我试图遵循标准的“官方”含义,但是我打算基于它的不同用法来定义这个术语(如下)。这就是说我将在本文的后续章节中进行更详细的探讨。

  1. 始于顶层 root(/)目录的整个 Linux 目录结构。
  2. 特定类型的数据存储格式,比如 EXT3、EXT4、BTRFS 以及 XFS 等等。Linux 支持近百种类型的文件系统,包括一些非常老的以及一些最新的。每一种文件系统类型都使用它自己独特的元数据结构来定义数据是如何存储和访问的。
  3. 用特定类型的文件系统格式化后的分区或逻辑卷,可以挂载到 Linux 文件系统的指定挂载点上。

文件系统的基本功能

磁盘存储是文件系统必须的功能,它与之伴生的有一些有趣而且不可或缺的细节。很明显,文件系统是用来为非易失数据的存储提供空间,这是它的基本功能。然而,它还有许多从需求出发的重要功能。

所有文件系统都需要提供一个名字空间,这是一种命名和组织方法。它定义了文件应该如何命名、文件名的最大长度,以及所有可用字符集中可用于文件名中字符集子集。它也定义了一个磁盘上数据的逻辑结构,比如使用目录来组织文件而不是把所有文件聚集成一个单一的、巨大的文件混合体。

定义名字空间以后,元数据结构是为该名字空间提供逻辑基础所必须的。这包括所需数据结构要能够支持分层目录结构,同时能够通过结构来确定硬盘空间中的块是已用的或可用的,支持修改文件或目录的名字,提供关于文件大小、创建时间、最后访问或修改时间等信息,以及位置或数据所属的文件在磁盘空间中的位置。其他的元数据用来存储关于磁盘细分的高级信息,比如逻辑卷和分区。这种更高层次的元数据以及它所代表的结构包含描述文件系统存储在驱动器或分区中的信息,但与文件系统元数据无关,与之独立。

文件系统也需要一个应用程序接口(API),从而提供了对文件系统对象,比如文件和目录进行操作的系统功能调用的访问。API 也提供了诸如创建、移动和删除文件的功能。它也提供了算法来确定某些信息,比如文件存于文件系统中的位置。这样的算法可以用来解释诸如磁盘速度和最小化磁盘碎片等术语。

现代文件系统还提供一个安全模型,这是一个定义文件和目录的访问权限的方案。Linux 文件系统安全模型确保用户只能访问自己的文件,而不能访问其他用户的文件或操作系统本身。

最后一块组成部分是实现这些所有功能所需要的软件。Linux 使用两层软件实现的方式来提高系统和程序员的效率。

图片 1:Linux 两层文件系统软件实现。

这两层中的第一层是 Linux 虚拟文件系统。虚拟文件系统提供了内核和开发者访问所有类型文件系统的的单一命令集。虚拟文件系统软件通过调用特殊设备驱动来和不同类型的文件系统进行交互。特定文件系统的设备驱动是第二层实现。设备驱动程序将文件系统命令的标准集解释为在分区或逻辑卷上的特定类型文件系统命令。

目录结构

作为一个通常来说非常有条理的处女座,我喜欢将东西存储在更小的、有组织的小容器中,而不是存于同一个大容器中。目录的使用使我能够存储文件并在我想要查看这些文件的时候也能够找到它们。目录也被称为文件夹,之所以被称为文件夹,是因为其中的文件被类比存放于物理桌面上。

在 Linux 和其他许多操作系统中,目录可以被组织成树状的分层结构。在 Linux 文件系统层次标准中定义了 Linux 的目录结构(LCTT 译注:可参阅这篇)。当通过目录引用来访问目录时,更深层目录名字是通过正斜杠(/)来连接,从而形成一个序列,比如 /var/log/var/spool/mail 。这些被称为路径。

下表提供了标准的、众所周知的、预定义的顶层 Linux 目录及其用途的简要清单。

目录描述
/ (root 文件系统)root 文件系统是文件系统的顶级目录。它必须包含在挂载其它文件系统前需要用来启动 Linux 系统的全部文件。它必须包含需要用来启动剩余文件系统的全部可执行文件和库。文件系统启动以后,所有其他文件系统作为 root 文件系统的子目录挂载到标准的、预定义好的挂载点上。
/bin/bin 目录包含用户的可执行文件。
/boot包含启动 Linux 系统所需要的静态引导程序和内核可执行文件以及配置文件。
/dev该目录包含每一个连接到系统的硬件设备的设备文件。这些文件不是设备驱动,而是代表计算机上的每一个计算机能够访问的设备。
/etc包含主机计算机的本地系统配置文件。
/home主目录存储用户文件,每一个用户都有一个位于 /home 目录中的子目录(作为其主目录)。
/lib包含启动系统所需要的共享库文件。
/media一个挂载外部可移动设备的地方,比如主机可能连接了一个 USB 驱动器。
/mnt一个普通文件系统的临时挂载点(如不可移动的介质),当管理员对一个文件系统进行修复或在其上工作时可以使用。
/opt可选文件,比如供应商提供的应用程序应该安装在这儿。
/root这不是 root(/)文件系统。它是 root 用户的主目录。
/sbin系统二进制文件。这些是用于系统管理的可执行文件。
/tmp临时目录。被操作系统和许多程序用来存储临时文件。用户也可能临时在这儿存储文件。注意,存储在这儿的文件可能在任何时候在没有通知的情况下被删除。
/usr该目录里面包含可共享的、只读的文件,包括可执行二进制文件和库、man 文件以及其他类型的文档。
/var可变数据文件存储在这儿。这些文件包括日志文件、MySQL 和其他数据库的文件、Web 服务器的数据文件、邮件以及更多。

表 1:Linux 文件系统层次结构的顶层

这些目录以及它们的子目录如表 1 所示,在所有子目录中,粗体的目录组成了 root 文件系统的必需部分。也就是说,它们不能创建为一个分离的文件系统并且在开机时进行挂载。这是因为它们(特别是它们包含的内容)必须在系统启动的时候出现,从而系统才能正确启动。

/media 目录和 /mnt 目录是 root 文件系统的一部分,但是它们从来不包含任何数据,因为它们只是一个临时挂载点。

表 1 中剩下的非粗体的目录不需要在系统启动过程中出现,但会在之后挂载到 root 文件系统上,在开机阶段,它们为主机进行准备,从而执行有用的工作。

请参考官方 Linux 文件系统层次标准(FHS)网页来了解这些每一个目录以及它们的子目录的更多细节。维基百科上也有关于 FHS 的一个很好的介绍。应该尽可能的遵循这些标准,从而确保操作和功能的一致性。无论在主机上使用什么类型的文件系统,该层次目录结构都是相同的。

Linux 统一目录结构

在一些非 Linux 操作系统的个人电脑上,如果有多个物理硬盘驱动器或多个分区,每一个硬盘或分区都会分配一个驱动器号。知道文件或程序位于哪一个硬盘驱动器上是很有必要的,比如 C:D: 。然后,你可以在命令中使用驱动器号,以 D: 为例,为了进入 D: 驱动器,你可以使用 cd 命令来更改工作目录为正确的目录,从而定位需要的文件。每一个硬盘驱动器都有自己单独的、完整的目录树。

Linux 文件系统将所有物理硬盘驱动器和分区统一为一个目录结构。它们均从顶层 root 目录(/)开始。所有其它目录以及它们的子目录均位于单一的 Linux 根目录下。这意味着只有一棵目录树来搜索文件和程序。

因为只有一个文件系统,所以 /home/tmp/var/opt/usr 能够创建在和 root(/)文件系统不同的物理硬盘驱动器、分区或逻辑分区上,然后挂载到一个挂载点(目录)上,从而作为 root 文件系统树的一部分。甚至可移动驱动器,比如 USB 驱动器或一个外接的 USB 或 ESATA 硬盘驱动器均可以挂载到 root 文件系统上,成为目录树不可或缺的部分。

当从 Linux 发行版的一个版本升级到另一个版本或从一个发行版更改到另一个发行版的时候,就会很清楚地看到这样创建到不同分区的好处。通常情况下,除了任何像 Fedora 中的 dnf-upgrade 之类的升级工具,会明智地在升级过程中偶尔重新格式化包含操作系统的硬盘驱动来删除那些长期积累的垃圾。如果 /home 目录是 root 文件系统的一部分(位于同一个硬盘驱动器),那么它也会被格式化,然后需要通过之前的备份恢复。如果 /home 目录作为一个分离的文件系统,那么安装程序将会识别到,并跳过它的格式化。对于存储数据库、邮箱、网页和其它可变的用户以及系统数据的 /var 目录也是这样的。

将 Linux 系统目录树的某些部分作为一个分离的文件系统还有一些其他原因。比如,在很久以前,我还不知道将所有需要的 Linux 目录均作为 root(/)文件系统的一部分可能存在的问题,于是,一些非常大的文件填满了 /home 目录。因为 /home 目录和 /tmp 目录均不是分离的文件系统,而是 root 文件系统的简单子目录,整个 root 文件系统就被填满了。于是就不再有剩余空间可以让操作系统用来存储临时文件或扩展已存在数据文件。首先,应用程序开始抱怨没有空间来保存文件,然后,操作系统也开始异常行动。启动到单用户模式,并清除了 /home 目录中的多余文件之后,终于又能够重新工作了。然后,我使用非常标准的多重文件系统设置来重新安装 Linux 系统,从而避免了系统崩溃的再次发生。

我曾经遇到一个情况,Linux 主机还在运行,但是却不允许用户通过 GUI 桌面登录。我可以通过使用虚拟控制台之一,通过命令行界面(CLI)本地登录,然后远程使用 SSH 。问题的原因是因为 /tmp 文件系统满了,因此 GUI 桌面登录时所需要的一些临时文件不能被创建。因为命令行界面登录不需要在 /tmp 目录中创建文件,所以无可用空间并不会阻止我使用命令行界面来登录。在这种情况下,/tmp 目录是一个分离的文件系统,在 /tmp 所位于的逻辑卷上还有大量的可用空间。我简单地扩展了 /tmp 逻辑卷的容量到能够容纳主机所需要的临时文件,于是问题便解决了。注意,这个解决方法不需要重启,当 /tmp 文件系统扩大以后,用户就可以登录到桌面了。

当我在一家很大的科技公司当实验室管理员的时候,遇到过另外一个故障。开发者将一个应用程序安装到了一个错误的位置(/var)。结果该应用程序崩溃了,因为 /var 文件系统满了,由于缺乏空间,存储于 /var/log 中的日志文件无法附加新的日志消息。然而,系统仍然在运行,因为 root 文件系统和 /tmp 文件系统还没有被填满。删除了该应用程序并重新安装在 /opt 文件系统后,问题便解决了。

文件系统类型

Linux 系统支持大约 100 种分区类型的读取,但是只能对很少的一些进行创建和写操作。但是,可以挂载不同类型的文件系统在同一个 root 文件系统上,并且是很常见的。在这样的背景下,我们所说的文件系统一词是指在硬盘驱动器或逻辑卷上的一个分区中存储和管理用户数据所需要的结构和元数据。能够被 Linux 系统的 fdisk 命令识别的文件系统类型的完整列表在此,你可以感受一下 Linux 系统对许多类型的系统的高度兼容性。

Linux 支持读取这么多类型的分区系统的主要目的是为了提高兼容性,从而至少能够与一些其他计算机系统的文件系统进行交互。下面列出了在 Fedora 中创建一个新的文件系统时的所有可选类型:

  • btrfs
  • cramfs
  • ext2
  • ext3
  • ext4
  • fat
  • gfs2
  • hfsplus
  • minix
  • msdos
  • ntfs
  • reiserfs
  • vfat
  • xfs

其他发行版支持创建的文件系统类型不同。比如,CentOS 6 只支持创建上表中标为黑体的文件系统类型。

挂载

在 Linux 系统上“ 挂载 mount ”文件系统的术语是指在计算机发展的早期,磁带或可移动的磁盘组需要需要物理地挂载到一个合适的驱动器设备上。当通过物理的方式放置到驱动器上以后,操作系统会逻辑地挂载位于磁盘上的文件系统,从而操作系统、应用程序和用户才能够访问文件系统中的内容。

一个挂载点简单的来说就是一个目录,就像任何其它目录一样,是作为 root 文件系统的一部分创建的。所以,比如,home 文件系统是挂载在目录 /home 下。文件系统可以被挂载到其他非 root 文件系统的挂载点上,但是这并不常见。

在 Linux 系统启动阶段的最初阶段,root 文件系统就会被挂载到 root 目录下(/)。其它文件系统在之后通过 SystemV 下的 rc 或更新一些的 Linux 发行版中的 systemd 等 Linux 启动程序挂载。在启动进程中文件系统的挂载是由 /etc/fstab 配置文件管理的。一个简单的记忆方法是,fstab 代表“ 文件系统表 file system table ”,它包含了需要挂载的文件系统的列表,这些文件系统均指定了挂载点,以及针对特定文件系统可能需要的选项。

使用 mount 命令可以把文件系统挂载到一个已有的目录/挂载点上。通常情况下,任何作为挂载点的目录都应该是空的且不包含任何其他文件。Linux 系统不会阻止用户挂载一个已被挂载了文件系统的目录或将文件系统挂载到一个包含文件的目录上。如果你将文件系统挂载到一个已有的目录或文件系统上,那么其原始内容将会被隐藏,只有新挂载的文件系统的内容是可见的。

结论

我希望通过这篇文章,阐明了围绕文件系统这个术语的一些可能的模糊之处。我花费了很长的时间,以及在一个良师的帮助下才真正理解和欣赏到 Linux 文件系统的复杂性、优雅性和功能以及它的全部含义。

如果你有任何问题,请写到下面的评论中,我会尽力来回答它们。

下个月

Linux 的另一个重要概念是:万物皆为文件。这个概念对用户和系统管理员来说有一些有趣和重要的实际应用。当我说完这个理由之后,你可能会想阅读我的文章:万物皆为文件,这篇文章会在我下个月计划写的关于 /dev 目录的文章之前写完。(LCTT 译注,也可参阅这篇

(题图 : wallup.net)


作者简介:

David Both 居住在美国北卡罗纳州的首府罗利,是一个 Linux 开源贡献者。他已经从事 IT 行业 40 余年,在 IBM 教授 OS/2 20 余年。1981 年,他在 IBM 开发了第一个关于最初的 IBM 个人电脑的培训课程。他也曾在 Red Hat 教授 RHCE 课程,也曾供职于 MCI worldcom,Cico 以及北卡罗纳州等。他已经为 Linux 开源社区工作近 20 年。


via: https://opensource.com/life/16/10/introduction-linux-filesystems

作者:David Both 译者:ucasFL 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出