《Nginx HTTP Server》

第1章:准备工作环境

在这一章中,我们将指导你通过这些步骤来准备工作环境,包括计算机和网站服务器。要想建立一个功能齐全的Nginx,需要理解许多事情,尤其是使用Windows操作系统的读者。

本章主题

  • 设置终端仿真器,用于通过命令行界面连接到远程服务器
  • 基本的Linux命令行工具,供不同阶段使用
  • 介绍Linux文件系统结构
  • 系统管理工具
  • 管理文件和权限

设置终端仿真器

对于过去十五年天天都在Windows操作系统下工作的我们来说,这个想法可能又使我们回到一个好的、老的基于命令行的界面,看起来好像稍微有点原始,但尽管如此,这对于大多数服务器管理员来说是必要的。第一个准备工作是下载和安装一个SSH客户端(Secure Shell, SSH),这是一个网络协议,通过这个协议能够使两个设备进行安全的通信,安全的保证在于交换的数据是加密的。它的作用显而易见,就是用于连接远程系统的shell,换句话说,就是在不损害安全的情况下能够控制服务器。

查找并下载PuTTY

在Windows操作系统下,对于使用SSH的访问者来说,PuTTY是一个使用广泛的终端仿真器。因此,可以在网上找到大量的文章和其他文档,该软件会提供各种不同的功能。我们将只涵盖与这里相关的功能——配置PuTTY连接服务器,输入文本,使用复制和粘贴命令。但应该知道还有很多免费的开源工具能够建立SSH通道,连接到Telent、Rlogin甚至是原始的TCP通信(raw TCP communication),等等。

可以直接从作者的网站下载PuTTY:

http://www.chiark.greenend.org.uk/~sgtatham/putty/

它只有一个单独的.EXE程序,不需要任各额外的文件。它的所有数据都保存在Windows注册表中,所以不会用配置文件来塞满你的系统。

建立会话

在继续阅讯之前,首先确定下列元素:

  • 准备连接的主机名和IP地址。
  • SSH守护进程的端口号,除非已知有其他端口号,否则该服务默认的是端口号是22。
  • 系统的一个用户帐号。
  • 帐号的密码

让我们快速看一下PuTTY的主要窗口(见下图)。

PuTTY会保存session中的设置,因此在完成各种参数配置后,确定指定该会话的名称后再单击Save按钮,如上图所示。

在默认的PuTTY界面上,需要填入想要连接的远程服务器的主机名(或者IP地址),然后配置运行在远程服务器上的SHH服务提供的端口号,SSHD默认的端口号是22。这里另外有几个设置选项,可能有用:

  • 在 Window 设置组,可能需要调整一些参数,例如终端窗口的大小和能够回显的行数。
  • 在 Window | Appearance 设置组,可以改变在终端窗口中显示的字体,字形及字号的大小,也包括光标选项。
  • 在 Window | Translation 设置组,可以指定不同的字符集,这对运行UTF-8字符集的服务器非常有用。
  • 在 Connection 设置组,可开启TCP keepalives功能,以防止TCP超时而导致断开。
  • 在 Connection | Data 设置组中,可以输入要连接的系统的帐户,然而由于安全的原因,PuTTY并不允许你保存用户的密码。

一旦完成会话的配置,记得再次保存,然后再开始单击主窗口上的Open按钮建立连接。如果是第一次连接到服务器,则需要通过接受服务器端的指纹(fingerprint)来证实它的真实性。如果以后再连接到同一台服务器,则不会再看到确认的信息,除非服务器设置(例如主机名或者是端口号)改变,或者是安全性被损坏,你连接到了一个中间的服务器(有人在中间攻击)。最后,提示注册(除非你激活自动登录选项)和密码。请注意,在键入密码的时候,密码是根本不会显示在屏幕上的——甚至不会以星号显示,因此要确保键入的密码准确无误,然后按Enter键。

使用PuTTY和shell

如果你以前从来没有使用过Putty或者系统shell,可以看看下面的详细介绍,涉及终端仿真器主窗口的一些行为。

  • 在终端窗口中,使用鼠标光标选择的文本在你释放鼠标左键的时候会自动复到剪切板。
  • 在窗口的任何区域,只要单击鼠标右键就会将剪贴板中的文本粘贴到终端窗口。
  • 使用快捷键Ctrl+C并不会把文本复制到剪切板,而是中断一个正在执行的程序。如果你意外运行一个超长时间执行的命令(所谓的超长时间是与你预计的时间相比较而言),则可以通过这个快捷方式来结束程序,从而再次出现shell。
  • 万一从服务器断开连接,则右击终端窗口的标题栏,打开一个菜单,然后选择“重新开始会话”。
  • 在命令行键入文件名的时候,可以通过Tab键尝试自动补全文件名。在使用Tab补全的过程中,如果听到“哔哔”的声响,这可能有两个原因:不是你键入的文件名片段(文件名的一部分)在系统中不存在,就是在系统中找到多个文件。如果是属于后一种情况,那么快速敲Tab键两次就会看到一个与已输入部分的文件名匹配的一个文件列表。注意,这个功能并非一直有效,这依赖于服务器运行的系统。

基本的shell命令

连接到服务器并打开一个终端窗口是一回事,能够实际使用则是另一回事。如果从来没有在Linux下工作过,你可能会发现这部份内容对你特别有帮助,它会帮助你了解最基本的和有用的命令。这里介绍的很多命令都将用于后面的章节,但是你很快会意识到在这里有很多命令需要使用。

文件和目录管理

在BASH((Bourne-Again SHell,GNU/Linux)发布时的默认shell)和微软的Windows命令提示行有限多相似之处,主要的相似在于我们使用的工作目录概念。shell提示输入一个命令,那么该命令会在当前的工作目录中执行。

第一次登陆shell帐户时,会进入你的home目录,这个文件夹一般包含你的个人文件,是一个私有的空间,如果没有特别指定访问权限,系统上的其他用户是不可进入该目录查看的。

下表列出了一些最有用的基本命令,它们用于文件和目录的管理。

命令名称描述
pwd显示当前所在的工作目录
[alex@example.com ~]$ pwd
/home/alex
cd
改变目录
[alex@example.com ~]$ cd images
[alex@example.com images]$ pwd
/home/alex/images
[alex@example.com images]$ cd /tmp
[alex@example.com tmp]$ pwd
/tmp
对于cd,有一些有用的快捷方式:
  • 键入cd 或 cd ~总能够让你回到home目录,然而更通用的用法是“cd ~”
  • 可以通过使用“cd ~/images”,进入用户主目录下的image目录
  • 键入“cd ..”会让你回到本目录的上一级目当,注意,cd和“..”之间有空格
  • 键入“cd .”,没有任何效果。然而要注意,“.”代表当前目录,例如可以使用“cd ./images”,进入当前目录下的images目录
ls列出当前目录或指定目录下的所有文件和目录
[alex@example.com ~]$ ls
images  photo2.jpg  photo.jpg  shopping.txt
试一下“ls –l”,显示与文件及目录相关的详细信息。选项“-a”显示隐藏文件和系统文件
mkdir新建一个新目录
[alex@example.com ~]$ mkdir documents
[alex@example.com ~]$ cd documents
[alex@example.com documents]$ mkdir /tmp/alex
[alex@example.com documents]$ cd /tmp/alex
[alex@example.com alex]$ pwd
/tmp/alex
一般的命令行应用程序没有输出任何文本的情况就是一个成功的操作。如果有错误发生,就显示一个信息
cp文件复制
命令语法:cp [选项] 源文件 目标文件
[alex@example.com ~]$ cp photo2.jpg photo3.jpg
mv移动或重命名文件
命令语法:mv [选项] 源文件 目标文件
文件重命名:
[alex@example.com ~]$ mv photo3.jpg photo4.jpg
把文件移到另一个目录:
[alex@example.com ~]$ mv photo4.jpg images/
rm删除一个文件或者一个目录。使用-r选项会使用递归功能:
[alex@example.com ~]$ rm photo.jpg
[alex@example.com ~]$ ls
images photo2.jpg shopping.txt
[alex@example.com ~]$ rm –r images/
[alex@example.com ~]$ ls
photo2.jpg shopping.txt
使用这个命令要慎重,尤其是以管理员的身份(这里指的是系统管理员)登录时,被删除的文件是不能恢复的(可以通过专用的软件进行恢复,不过也不是十分把握)。一个简单的“rm -rf /” 命令足以“洗白”你的整个文件系统
locate在整个文件系统上找出指定的文件,该命令直接与updatedb关联:
[alex@example.com ~]$ locate photo2.jpg
/home/alex/photo2.jpg
/home/jesse/holiday_photo2.jpg
注意:命令locate完全依赖于索引,如果新建了一个文件,你是找不到它的,除非你使用下面的命令执行过数据库升级
updatedb更新文件数据库。注意,该命令需要使用管理员权限,因此,一般通过cron job,就是计划任务(相当于Windows操作系统中的任务管理)来实现一个定时更新:
alex@example.com ~]$ mkdir "Holidays in France"
[alex@example.com ~]$ locate France
No file found: a database update is required.
一旦以管理员的帐户进入,就可以执行该命令:
[root@example.com ~]# updatedb
[root@example.com ~]# locate France
/home/alex/Holidays in France
man显示指定命令的使用帮助
[alex@example.com ~]$ man ls
以下是屏幕截图
[alex@example.com ~]$ man ls

最后,可以使用clear命令来清除屏幕上的所有文本,然后重新开始。

用户和组管理

对于管理员来说,首要的困扰就是在他们的系统上有哪些用户,这些用户要访问哪些资源。在这方面,基于Unix的操作系统提供了一个详细的用户和组的管理机制。

超级用户帐户

每一个操作系统中都有一个超级用户帐户,经常需要执行管理员级别的任务,这个帐户通常叫root,然而在一些操作系统上也叫其他名字(例如admin或者甚至是toor)。超级用户能够访问系统中所有的文件和目录,有权读取、编辑和执行所有的文件,也可以改变文件的属性和访问权限。

但是还是不推荐用机器的超级用户长期连接远程机器。实际上,一些操作系统(例如Ubuntu)甚至都不允许你这么做。计算机安全的一个最基本的原理,即最小权限,你永远不允许做你分外的事情。换句话说,如果你只打算给一个使用你计算机用户上网和使用Open Office编写文档的能力,那么为什么给他能够访问系统配置目录的权限呢?对用户授予比需更多的权限只会导致系统的安全性和完整性被损坏。正是由于这个原因,所以强烈推荐你建立一个用户帐号,这样做不仅方便限制机器上的个人用户,也是为了确保应用程序要运行在一个具有明确界定的安全环境中。

用户帐户

在Linux文件系统中的配置目录(一般是/etc目录)中保存着系统用户的列表:/etc/passwd,然而用户的密码并没有保存在该文件中。由于安全原因,在大多数情况下,这些用户密码保存在一个独立文件/etc/shadow中,不过该文件还是提供了每一位用户的一些信息。在文件passwd中,每一行对应一个用户,语法格式如下,而且必须遵循此格式:

Name:password:ID:group ID:comment:home directory:login shell

在实际的文件中,“password”部份被 “x”所替代,它指出密码实际保存在文件/etc/shadow中。

增加一个新的用户就是只是在文件/etc/passwd中添加这么一行。然而,你可能会发现手动处理稍微有点麻烦,在这种情况下,你会很高兴地去学习一个能够自动操作的程序,而且发布的版本中也包括这样的工具,即useradd。

对于这个命令,基本的语法是useradd username,这将建立一个新的用户帐户,同时包括默认的设置(当然也可以定制)。默认的设置包括:一个home目录,位于/home;没有有效期;默认的组;登录的Bash shell。如果添加的帐户是用来运行服务,例如Nginx,则建议不要授予该用户帐户shell的访问权限,因此你要确定登陆shell设置为nologin(通常的设置/sbin/nologin),因此,应该用以下格式命令添加该用户:

useradd --shell /sbin/nologin nginx

也可以定制该用户home目录的位置,比如定制到Nginx的安装目录(实际上这样写更稳妥:useradd -s /sbin/nologin -d /usr/local/nginx nginx)

useradd --shell /sbin/nologin --home-dir /usr/local/nginx nginx

最后这个nginx指的是要创建的这个用户帐户的名称。

在帐户建立完成后,如果想对该帐户修发一些参数,可以使用usermod命令。允许对帐户名重命名,修发帐户密码,移动home目录到其他位置,等等。最后,可能还想删除一个用户帐户,可通过命令userdel来完成,格式很简单:userdel username,使用-r选项还可以同时删除home目录

记住,所有这些命令都可以通过man命令获取详细信息,从而得到帮助,例如:man useradd。

组管理

除了用户帐户外,基于Unix的操作系统还提供了更高级的资源管理机制——用户组。其目的在于让同一个组的成员对某一文件和目录共同的访问权限,每一个进入该组的用户都继承该组的权限。管理用户可以属于其他组(secondary group),但是一个用户帐户至少属于一个组——主要组(primary group)。

在实践中,用户组的列表保存在文件/etc/group中,在文件中,每一行代表一个组,它的语法描述如下:

Group name:password:group ID:user list

用户组密码很少全名用,在该文件中实际存储的是一个“x”,它表示该组没有密码。在每一行的结尾,你会看到属于该组的用户列表。下图是一个生产环境服务器的用户组文件。

此外,如果想在系统中建立一个新的用户组,则有两个选择:(1)在文件/etc/group中添加新的一行;(2)使用专用的groupadd命令添加,它的语法很简单:groupadd groupname,它也有一些典型的参数,可以通过man groupadd了解。

类似于系统用户管理,也可以找到命令groupmod和groupdel,分别用于修发和删除组。更重要的是,如何将一个用户添加到一个用户组?有两种方法:(1)手工编辑/etc/group文件,将用户名添加到相应的组,在组的末尾添加上希望添加的用户;(2)可以使用下列命令来完成:

usermod --append --groups groupname username

你可能会指定一个或多个组。如果将选项--append移走,会得到以下结果:在命令中指定的组取而代之该用户现有的组。最后,可以通过命令groups来显示一个用户都属于哪些组。

程序和进程

在shell中运行一个程序不是简单地键入该文件和文件名。对于Bash处理执行二进制的脚本文件的方法,有些不易察觉的细节,你需要理解一下。

运行应用程序

想执行程序或者脚本的时候,需要面对三种不同的情况。

  • 要执行的程序就在当前工作目录下
    解决方法:在要执行的文件前面加上“./” (句点和斜线), 这么做的原因是强迫shell在当前的工作目录中查找要执行的文件。
    示例如下:
    [alex@example.com ~]$ cd programs
    [alex@example.com programs]$ ./my-app
  • 要执行的程序不在当前的工作目录下,但你知道该文件的路径。
    解决方法:键入该文件的完整路径。
    示例如下:
    [alex@example.com ~]$ /home/alex/programs/my-app
  • 要执行的程序位于环境变量PATH指定的值内。
    解决方法:直接键入文件名,而不用指出其路径。
    示例如下:开始使用nano文本编辑器,通常能够在系统目录/usr/bin找到(/usr/bin在PATH内)。
    [alex@example.com ~]$ nano

注意,在运行shell命令时,shell的提示符是不会再出现的,除非该命令执行完毕。这种情况下会是个问题,如果有一个漫长的处理过程,在这个过程中你将无法做任何事情,因此,你可能会想在开始运行一个程序后,让它在后台运行,而不是在shell界面下完成执行,这也很容易,在执行的命令行后添加一个“&”字符即可。示例如下:

[alex@example.com tmp]$ cp home.avi ~/movies/ &
[6] 2629
[alex@example.com tmp]$ [6]   Done     cp home.avi ~/movies/ &

一旦发送命令,该进程的pid(进程标识符)就会显示在屏幕上,并且回到shell提示符。一旦执行完毕,除了用于开启该进程的原始命令之外,还会出现一条信息,指出该命令执行完毕。

系统服务

许多运行在后台的应用程序(通常指的是可以通过services命令来启动的程序),都不是通过在命令后简单加上一个&字符,而是通过一个复杂的脚本来管理它们的启动和停止。这些脚本可以放置在各自的目录内,但最普遍的是在目录/etc/init.d内。

一些Linux发布版本中,例如Red Hat, Fedora, CentOS和Mandriva,提供了一个service脚本,可以通过它来控制服务。通过使用service name command语法来实现,在这里service是脚本命令,name指要操作的服务,command是下表中的命令之一。如果在你所用的发布版本中没有提供service脚本,可以使用类似这样的语法来执行:/etc/init.d/name command。注意,init.d脚本不一定提供所有这些常用的命令。

命令名称描述
start启动指定的服务
stop通过干净的方式(clean way)停止指定的服务
restart重新启动指定的服务
reload重新装载指定服务的配置文件
status显示指定服务的状态

尝试一下service --status-all,它会列出所有系统服务的当前状态

进程管理

正如以前提到的,系统会为运行在计算机上的第一个进程提供一个数值,这个数值就是进程标识符(pid)。毫无疑问,pid对于各种不同的环境都很重要,有些重要性可能还需要你去进一步发现。

查找pid

首先,如何查找发现一个进程的pid?尽管有许多方法可以得到它,但是使用最多的还是一个简单的工作——ps。它有很多选项(可以和管道机制组合)能够帮你找到进程的各种详细信息。

ps aux | grep sshd命令可以分为三部分。

  1. ps aux命令列出当前系统中运行的所有进程。
  2. |(pipe)是重定向管道。重定向命令的输出,将管道命令之前的命令输出重定向到管理命令后的命令中,作为该命令的输入。运行ps aux会产生一个很长的进程列表,但是因为这里只需要显示一个进程,因此使用了grep过滤命令。
  3. grep sshd从ps aux命令的输出中获取只包含指定关键字的行。换句话说,grep负责的是过滤,保留了包括sshd的行。

管理员最好的朋友——top

如果你的系统上运行着一个高流量的网站,那么另一个工具特别有用,它就是top,它列出了在当前系统下运行的所有进程,并且列出了进程的pid,默认顺序以进程对CPU的使用情况排序(如果想以其他指标排序,可查看man top。该命令有许多用法。)。这个显示每秒钟会自动刷新一次,直到你中断它的执行(例如可以通过执行Ctrl+C键中断)或者是通过按Q键退出应用程序。可以通过这个工具了解和追踪最消耗资源的进程。

大写字母部分提供了大量有用的统计数据,主要是当前系统上资源的使用情况,例如正常运行的时间、正在活动的用户、平均负载、内存和CPU的使用情况等。

杀进程

如果一个正在执行的命令发生错误并且不返回提示符,可以使用一种解决方法,即按快捷键Ctrl+C中断这个应用程序。通过kill命令,同样的操作能够应用于后台进程。有一点需要说明,不能在kill之后指定进程的名称,而是为它提供程序的pid,这么做的原因显而易见,同一个程序可能会被执行多次,它们的进程名相同,但每次执行的pid却不同,所以一个程序名不一定总是对应于独一无二的进程:

[alex@example.com ~]$ kill 12075

此外,如果执行该命令没有任何结果输出,也没有必要担心。实际上,如果输入的是一个无效的pid,那么可能kill命令才会提示你。kill命令是简单的发送一个信号给指定进程,这并不一定意味着该进程已成功停止。如果该程序被锁定,那么该信号不会响应进程的执行,程序将继续运行。不要急,有一种简单的处理方法能让你恢复信心,即选项“-9”,它能够强迫进程立即结束。

[alex@example.com ~]$ kill -9 12075

最后,正如你所想的,在某些时候你可能需要依次结束多个进程。例如,需要杀掉Apache产生的所有进程。如果是这样,我们可以使用一个稍微不同的命令——killall,它与kill命令稍微有不同,killall命令接受进程名作为参数,而不是pid。

[alex@example.com ~]$ killall httpd

了解Linux文件系统

Linux操作系统有自己组织文件的方法,也是一种非常特殊的组织方法,近似于历史悠久的文件系统等级标准FHS(Filesystem Hierarchy Standard)。根据FHS官方的文档,这个标准的作用是:

  • 软件预定(predict)安装文件和目录的位置;
  • 用户预定(predict)安装文件和目录的位置。

尽管FHS的原始标准规范是在1933年公布的,但它仍然供现代发布的Linux使用,不过略有修改,使用的是修订版本。

目录结构

不像Windows操作系统一样——在Windows操作系统中,所有文件路径总是以一个字母开头(可以想像一下,如果系统中有多达26个驱动器的时候会是什么情况?)——基于FHS的文件系统有一个共同的父目录,该父目录叫根(root)目录,也就是众所周知的“/”(斜线字符)。所有文件和目录(不管是设备、驱动器或分区,它们挂载于本地)都是根目录的子目录(children),因此在本书中,所有的绝对路径总是以斜线开始的(见下表)。

让我们现在开始运行cd/,要了解通过FHS定义的许多子目录,接着运行ls。请注意,该目录结构纯粹是传统的目录结构,你可以在该目录下或者其他目录下放置你自己的文件和建立更多的目录。

路径名称描述
/根目录:不要与/root混淆,根目录下通常没有文件,尽管没有任何人阻止你这么做。
/bin二进制文件目录:系统中的可执行二进制文件或脚本文件通常都放在该目录,该目录对于系统上的所有用户可见。例如,一些常用的命令ls、cp或者mv等都可以在该目录下找到。
/bootboot目录:存放系统启动时的关键文件。
/dev设备:该目录存放设备文件和特殊文件,更多的信息参见下一节。
/etc配置文件目录:系统中服务和应用程序的配置文件目录,你可能会经常浏览这个目录,例如,在需要编辑Nginx服务器的设置或添加虚拟主机的时候。
/home主目录:该目录包含本系统上除root用户外其他所有用户的主目录。例如,目录/home/alex为系统用户alaex的home目录。
/lib库文件目录:用于存放/bin和/sbin目录下的二进制文件需要的共享库文件和内核模块。
/media可移动介质目录:该目录能使你轻松访问可移动介质的目录,挂载点用来挂载CD-ROM、USB等设备。
/mnt临时挂载文件系统:该目录适合管理员临时挂载一个文件系统。
/opt可选的软件安装包:理论上,这个目录应该安装一些应用程序文件和附加的安装包(在安装系统是没有默认安装),但是在实际使用中,该目录基本不使用。
/proc内核和进程信息的虚拟文件系统:该目录提供了访问虚拟文件系统的桥梁,它包含各种状态信息和关于所有进程的详细信息。
/rootroot用户的home目录:用户root,也就是众所周知的超级用户(Superuser),它不像普通用户一样存储在/home目录下的home目录。取而代之的是/root目录,即斜线“/”和root,注意,这里的root不能和根(root)目录“/”混淆。
/sbin系统二进制文件目录:该目录中的工具供系统管理员使用,因此一般情况下只有root用户才可访问。例如,程序ifconfig,halt,service等其他许多的程序都能在这里找到。
/srv服务器数据:该目录用于存放来自于系统的服务产生的数据。就像其他目录一样,它只是占用一个目录而已,该目录很少使用。
/tmp临时文件目录:在程序执行时,不需要保护的文件应该放在这里。实际上,许多操作系统在重新启动后就会清除该目录中的内容。
/usr只读的用户数据:该目录是第二个层次分级目录,它提供了只读的共享数据。/usr目录包含下列目录:
  • /usr/bin: 不重要的二进制命令和脚本文件,所有用户均可使用(例如wget,gzip,firefox等)
  • /usr/include: 该目录下是头文件,如来自C的库文件,有些程序在编译时会包含该目录下的这些文件
  • /usr/lib: 由/usr/bin和/usr/sbin下的程序调用的库文件
  • /usr/sbin: 不重要的系统二进制命令和脚本文件,对于所有的用户是可用的(例如,useradd和ntpdate等)
  • /usr/share: 与系统结构体系无关的数据文件
  • /usr/src: 内核源代码和安装应用程序的源代码
  • /usr/X11R6: 与X Window系统(v11 release 6)-关于的文件
  • /usr/local: 一个第三层的目录结构,仅用于本地数据
/var变化的文件:在去行应用程序或是服务中,这些文件会发生预期变化,例如,logfiles,cache,spool,等等。它有自己的层次结构:
  • /var/lib: 应用程序或更普遍的说法是操作系统依赖的变量状态信息。注意,MySql数据库的变量信息通常存储在/var/lib/mysql
  • /var/lock: 锁文件(lock file)用于应用程序之间的同步资源访问
  • /var/log: 由程序、服务或内核产生的日志文件
  • /var/mail: 基于用户邮件的文件。在更多的系统中,/var/mail也只是一个简单的快捷方式,实际文件位于/var/spool/mail中
  • /var/run: 运行中的可变数据。在系统重新启动后原有的数据将消失,该目录提供的信息是从系统被启动开始到现在的有关信息
  • /var/spool: 这个目录放在文件是要处理的文件,例如邮件和打印作业
  • /var/tmp: 一个占位符,用于存放系统重新启动时不应删除的临时文件

特列文件和设备

你可能在目录结构中注意到,Linux操作系统有一个预留目录(/dev),用于存入“设备文件”。事实上,这个目录包含的元素称为节点,每一个节点在系统上代表为一个不同的设备,它们是实际的硬件设备或者是伪设备,无论哪种情况,作为文件系统的一部分将它们列出来,其目的是配合程序和服务的输入和输出,使它们更加便利——软件开发人员能够方便地访问这些设备,因为他们要读写文件。应该学习设备文件,很多时候需要使用它,或者说迟早会使用到它们。

设备类型

在/dev目录内,可能会有大量有效的设备,不幸的是,它们中大多数设备都有一个不出名的名字,几乎不可能看出其用途,设备文件的命名采用的是Linux操作系统的协定。由于在系统中可能存在很多设备,因此我们将仅识别出最常见的一些。设备的名称由一个前缀组成,按照惯例,这个前缀用于定义设备的类型,并且如果同一个类型的设备有多个出现在当前系统中,那么在设备之后会有一个数字或者是字母,以示区分。

下面列出最常见设备文件类型的常规前缀:

  • cdrom: CD 和 DVD-ROM 驱动器
  • fd: 软盘驱动器
  • hd: IDE连接设备,例如硬盘驱动器和CD-ROM
  • md: Metadisks 和 RAID 设备,例如硬盘
  • ram: RAM 磁盘
  • sd: SCSI连接大容量存储设备
  • usb: USB连接设备
伪设备

列在目录/dev目录下的一些设备并不相当于实际的硬件设备,相反,它们是为了提供给管理员和开发者访问特殊资源的简单输入或是输出。出于这个原因,我们称它们为“伪设备”(Pseudo device)。下表列出最常用的伪设备,简单描述如下。

伪设备描述
/dev/nullNull设备
这个伪设备经常被称为黑洞(black hole),因此它的目的是忽略发送给它的一切数据。向它写数据时,它始终报告写操作是成功的;向它读取数据时,该设备总是返回没有数据。
如果你不想要将一个程序输出重定向到任何地方,这是特别有用的。换句话说,如果你想确保一个命令执行,但又不想把文字输到屏幕上,则可以像下面这样:
[alex@example.com ~]$ cat shopping.txt > /dev/null
/dev/random随机数生成器
/dev/urandom流设备生成随机数数据流。/dev/random生成真实的随机数,而/dev/urandom提供伪随机数。
它们产生的是二进制数据,来自己/dev/random和/dev/urandom的数字不能够显示在终端控制台(它们看起来像是垃圾数据流),这些设备通常由开发人员使用,希望收集到可信(reliable)的随机数
/dev/fullFull设备
该伪设备是一个流设备,向它写入时,会返回错误,因为它总被认为是满的;用户或程序读取它时,它返回一个无限空字符流。
伪设备/dev/full为管理员和程序员提供了一种操作,一旦被触发就会返回错误。
[alex@example.com ~]$ echo Hello! > /dev/full
~bash: echo: write error: No space left on device
/dev/zeroZero数据
与/dev/null极其相。写完成后,zero伪设备总是提供成功的返回代码。然而,在从这个设备上读取时,它输出一个无限空字符流。
有各种各样的例子可以证明读设备/dev/zero有用,例如,作为程序的输入为它提供数据,将生成一个指定大小的文件,或者是为了格式化存储设备而写入
挂接存储驱动器

正如你可能在前面几节已经注意到,在/dev目录中,有些可用的设备是存储设备,例如硬盘存储器、固态硬盘(SSD)、软驱或CD-ROM。然而访问它们提供的内容不只是简单地使用cd命令进入驱动器访问,存储驱动器需要挂接到文件系统,换句话说,驱动器需要附加到一个固定的目录。

[alex@example.com ~]$ cd /dev/md1
~bash: cd: /dev/md1: is not a directory.
[alex@example.com ~]$ mount /dev/md1 /mnt/alexdrive
[alex@example.com ~]$ cd /mnt/alexdrive
[alex@example.com alexdrive]$ ls
Documents Music Photos Videos boot.ini

命令mount允许你将一个驱动器(第一个参数,/dev/md1)附加到系统中现有的目录(第二个参数)。一旦驱动器被挂载,你就可以使用文件系统的任何指令访问驱动器。

在现在的Linux发行版本中,CD-ROM和其他一些常见设备能够由系统自动挂接。

如果你想获取当前挂接系统中设备的挂接情况,使用mount命令来完成这个工作——它会告诉你系统中每一个被挂接的驱动器及使用中的文件系统,如下图所示。

如果想让一个驱动器在开机的时候能够自动挂接,或者简单设置一个目录作为一个驱动器的默认挂载点,则需要编辑/etc/fstab文件,这需要你具有管理员的权限,该文件是一个简单的文本文件,可以使用文本编辑器(例如nano)来打开。然而,该文件遵循一个特殊的语法,一些不知不觉的改变可能会招来很多足以毁灭系统的可能,fstab更详细的语法可在tuxfiles.org之类的网站找到。

最后,如果需要从一个正在使用的计算机移除一个设备(例如,移除USB存储器),那么你首先需要使命令将其卸载,卸载设备的命令是:

[alex@example.com ~]$ umount /dev/usb1

注意,命令的第一个参数可以是驱动器的名称或者是挂载点,处理的结果相同。

文件和inodes

在提及Unix操作系统的时候,“文件系统”的概念普遍被误解。由于这些系统遵循FHS,所以它们使用一个共同的目录层次结构重组了所有文件和设备,然而,存储设备可能有自己独立的磁盘文件系统,一个包含大量存储设备(硬盘驱动器,CD-ROM,等等)的磁盘文件系统被设计为组织文件。Windows操作系统更喜欢使用FAT,FAT32或NTFS,然而,在Linux操作系统下,默认且也是最受推荐的文件系统是EXT3。EXT3有许多特征,对于管理员来说,要想完全理解操作系统提供的EXT3,必须掌握FHS。

EXT3文件系统

不像Windows系统中古老的FAT32文件系统只允许文件大小为4GB,EXT3文件系统下单个文件的大小限制为16T(依赖于块的大小)。此外,在驱动器上使用EXT3文件系统最大的存储空间为32TB,因此你应该无忧无虑地使用许多年,除非使用存储器的能力猛涨。EXT3有趣的特点之一是,它设计的数据存储方式,能使文档碎片除到最低限度,同时又不会影响系统性能,因此,不需要对驱动器进行碎片整理。

文件名

EXT3文件系统可以接受长度为256个字符的文件名,尽管扩展名通常显示文件内容类型,例如a.txt文件表示一个文本文件,它应该包含有文本内容,a.mp3文件用户表标一个音乐文件,等等,但是EXT3不需要文件的扩展名。有一个重要的事实需要注意,即在EXT3的文件系统中,文件名区分大小写——可能你已经发现,在同一个目录中,文件名“SHOPPING。TXT”,“Shopping.txt”或“shopping.txt”分别表示不同的文件。

节点(Inodes)

Linux的文件系统(例如EXT3文件系统)会为每一个文件存储大量的信息,而这种信息被分为逻辑信息和物理信息——存储在称为inode特定结构中的信息和实际的文件数据。一些被包含在inode中的数据指出系统如何恢复驱动器上文件的内容,但这还不是全部——inode还包含文件权限,用户和组的所有权,文件大小,访问和修改时间,等等。注意,它不包含实际的文件名。

在磁盘上的每一个节点都有一个唯一的标识符,这个标识符被称为节点号(inode number)或i-number,可以在各种情况下使用。可以通过使用ls -i检索文件的节点数(见下图)

atime, ctime和 mtime

元数据中包含一个inode,你会发现有关文件的三个不同时间戳,分别为:atime,ctime和mtime(见下表的描述)

时间戳描述
atime访问时间
表示文件最后被访问的时间和日期。每一次应用程序或服务使用系统调用读取一个文件时,文件的访问时间都会更新
mtime修改时间
表示文件被修改的时间和日期。文件的内容发生改变时,文件的修改日期将随之更新
ctime更改时间
表示文件上次被修改的时间和日期,这个时间戳关系到文件属性(换句话说,文件的节点inode的改动)和文件数据

必须理解mtime和ctime之间的不同,修改时间(Modification time)仅关系到文件的ovgt据,而更改时间(Change time)会同时跟踪文件属性和数据。下面有一些常见的例子说明了这三种机制。

文件访问时间(atime)

[alex@example.com ~]$ nano shopping.txt

文件被文本编辑器打开后,它的内容也就被访问。同时该文件的访问时间更新。

文件更改时间(ctime)

[alex@example.com ~]$ chmod 0755 script.sh

文件权限被更新(chmod命令在后面的章节中讲述),inode中的信息也随之改变,这个命令执行的结果是文件的更改时间被更新。

文件修改时间(mtime)

[alex@example.com ~]$ echo "- a pair of socks" >> shopping.txt

文件数据被更新,因此,文件的修改时间和文件的改变时间都随之更新。

正如你可能已经注意到的,在inode中没有文件和目录建立的时间记录,因此如果想要查找文件是什么时候创建的,将不可能。至于为什么把这样一个重要的因素排除在外,目前还不清楚。如果想知道与文件相关的所有时间戳,可以使用stat命令:

[alex@example.com ~]$ stat shopping.txt

对于SSD固态驱动器用户很重要
事实证明,SSD固态允动器(Solid-State Drive)会使文件系统的访问时间功能下降,能够使驱动器性能下降显著,因为无论何时读取一个文件,都需要更新其inode。因此,对于频繁进行写操作的情况,使用这种类型的存储设备显然是一个重大的问题。放心,对于这个已经存在的问题,也有一个简单的解决方法,即禁用文件的访问时间更新。这可以通过一个挂接选项来解决——noatime。将该选项在文件/etc/fstab中指定(如果想永久不变地添加)。你可以简单用noatime ssd查找更多的文档,这归功于Kevin Burton的重大发现。

符号链接和硬链接

Linux中的符号链接相当于Windows操作系统中的快捷方式,但仍然有些不同,需要解释一下,最重要的是,读写该文件的应用程序的访问实际上会影响到链接的目标(即被链接的文件)而不是链接本身。然而,cp或rm影响的是连接而不是目标。

建立链接是通过ln -s命令来完成的,这里有一个例子可以帮助你理解符号链接:

[alex@example.com ~]$ lns shoppinglist.txt link_to_list
[alex@example.com ~]$ ls
link_to_list photo.jpg photo2.jpg shoppinglist.txt
[alex@example.com ~]$ cat link_to_list
- toothpaste
- a pair of socks
[alex@example.com ~]$ rm link_to_list
[alex@example.com ~]$ ls
photo.jpg photo2.jpg shoppinglist.txt

正如你看到的,可以通过符号连接读取被链接的文件。如果删除该链接,目标文件不会受到影响,复制操作也是一样的(是链接自身的复制,而不是目标文件)。

除了与Windows快捷方式不同之外,另一个不同是它可以使用相对路径链接文件。这使嵌入归档文件内的链接特别有用——用户可能提取文件到系统上的任何位置,使用绝对路径部署快捷方式将毫无意义。

最后,Windows快捷方式有包括额外的元数据的能力,这允许用户选择一个图标,分配键盘的快捷方式,等等,然后,符号链接是简单的链接目标文件的路径及其本身,它们不提供同样的能力。

在Windows中,另一个类型的链接无效,那么就是硬链接(hard link),它们的功能稍微有点不同,硬链接表现为连接到文件的数据,两个或更链接可以链接到存储器上的同一个数据,当这些链接中的任何一个被删除后,数据自身不受影响,其他的链接仍然指向该数据,如果把它们链接的目标文件也删除,则在最后一个链接被删除后,数据也将从存储器中移除。

下面举例说明,让我们为shoppinglist.txt文件建立一个硬链接,使用同样的命令ln,但是没有开关选项-s:

[alex@example.com ~]$ ln shoppinglist.txt hard_link_to_list

如果决定删除文件shoppinglist.txt,但是hard_link_to_list仍然留在这里,它指向的数据仍然有效,另外,新建的链接对于一些命令(例如ls),被 作为一个实际的文件。如果运行ls命令计算所占的这个目录总文件大小,会发现链接文件的大小会被 加上,如果shoppinglist.txt文件自身的大小占用磁盘空间为5KB,那么被ls报告的总数为10KB——5KB为shoppinglist.txt文件自身的大小,5KB为链接自身的大小。然而,一些工具,例如du(用于显示磁盘使用量,后面会讲到),能够更进一步报告实际占用的存储空间。

文件处理

下一个学习方向是Linux shell,如果在命令行界面熟练处理文件,通过这些简单的工具能够完成很多操作:编辑文件,压缩文件和目录,修改文件属性,等等。但是,现在让我们从一个更简单的话题出发——显示文件。

读取文件

首先,需要理解与我们一起工作的终端,换句话说,在这里不可能使用图形数据,只能够将文本显示在屏幕上,在这个意义上,就是处理指定文本文件了,不能够将二进制文件显示在屏幕上,例如,图表、视频等其他格式的二进制数据文件。

在终端上显示文本文件最简单的方法是使用cat命令,例如,下图所示的例子:

但是cat命令还能够执行更复杂的操作(例如,将多个输入的文件连接为一个文件),它格式简单,语法为cat filename,文件filename的内容将显示在标准的输出设备上——换句话说,在这里指的就是终端显示屏,也就是你的显示器。

如果重新使用grep机制,前面的进程管理部分接触过grep,那么对于下面的过滤,能够获得感兴趣的内容:

[alex@example.com ~]$ cat /etc/fstab | grep sys
/dev/sys     /sys      /sysfs      defaults     0  0

正如你看到的,管道命令输出到命令grep,在grep命令后设置指定过过滤的字符串,任何没有包括指定字符串的行都不会显示。

为了以不同的方式显示文本,也可以将管道输出指向其他程序。例如,你的文件碰巧是一个大的文本,它可能不太合适当前的终端窗口,那么解决的方法为将管道转向more命令,例如下图所示的例子。

这样可以便好的控制文件流——它显示的行数和终端所能容纳的行数一样,直到你按下回车键(Return key)显示下一屏,按下Q或Ctrl+C返回shell提示符。

更妙的是less命令,允许你在文件流中上下滚动,它不像cat那样需要管道符,而less命令获自己就可以完成:

[alex@example.com ~]$ less /etc/php.ini
编辑文件

如果你是一个长时间使用微软Windows或Mac OS操作系统的用户,那么学习这么一个高级命令行文本编辑器确实会感到很吃惊,以下提到的这几个命令行文本编辑器在大多数Linux发行版本中都有提供:vim,emacs,nano等等。这里有一个问题——即应该选择哪一个文件编辑器?既然你读到这里,那么你最好的选择应该是nano,这已在前面的章节中提到。

nano是一个用户界面友好的文本编辑器,与它一起提供的是大量有趣的功能——高亮度语法、文本查找和替换及快捷键(keyboard shortcut)。不像它的竞争对手一样,通常需要一个长的学习过程,与其他文本编辑器有明显区别的是,nano的界面很直观,如下图所示。

由于在这个命令行控制的界面下没有鼠标光标,所以界面通过快捷键来控制,各种有效的操作都显示在底部的命令栏中。编辑完成后,保存(Ctrl+O)并退出(Ctrl+X)。注意,在底部有效的命令列表中,字符“^”表示控制(Control)组合键(^G代表Ctrl+G,^O代表Ctrl+O,等等)。

然而,向文件写入还有其他的方法,所使用的命令不需要任何界面,其中一个可行的方法就是重定向机制,它允许你为输入或输出流指定一个位置,通过shell命令进行交互,换句话说,在默认情况下,文字显示在屏幕上,但是你可以使用这种机制指定到其他的地方。对于重定向机制来说,最常见的用法是将一个命令的输出写入到一个文件。下面的例子说明了它的语法:

[alex@example.com ~]$ ls /etc > files_in_etc.txt

该命令执行后通常没有任何文本输出到屏幕,实际上文本已经被保存到你指定的文件中,符号“>”允许你把文本写的文件中,如果指定的文件已经存在,原始的内容会被删除和替换。在这个例子中,我们列出了/etc目录下的文件,并且作为一个结果保存在一个文本文件中;如果使用符号“>>”,可将上面命令的输出添加到指定的文件(如果不存在,则新建一个):

[alex@example.com ~]$ ls /etc/init.d >> files_in_etc.txt

/etc/init.d目录中的文件都是文本文件,将该列表追加到一个文本文件。

最后,touch命令用于更新一个文件的访问日期和修改日期,虽然它实际上并没有编辑文件的内容,但功能确实如此:

[alex@example.com ~]$ touch shopping.txt
压缩和归档

虽然ZIP和RAR压缩格式很流行,并且广泛应用于互联网,它们都是专利技术软件,所以并非Linux世界的主流选择,其他格式,例如Gzip和bzip2是幸运的。当然,对于Linux,ZIP和RAR解决方案都有。但是你会发现在Linux系统下,多数项目下载的归档文件都是.tar.gz或.tar.bz2文件。

正确读取文件名,这里有两个扩展名——tar和gz(或bz2),第一部分指出将文件组成到一起的方法,第二部分显示使用的压缩算法,Tar(是Tape archive,磁带归档之意),它是一个把多个文件连接为单个文件的工具,被压缩的单个文件称为tarball,一旦这个建立tarball建立,就可以给定一个压缩选项,提供各种各样的算法。该工具在大多数Linux发布版本中都有,然而在一些很小的系统中,可能必须用系统中的包管理器手动安装(后面有介绍)它。

使用gzip和bz2建立barball的压缩包的语法各自如下:

tar czvf archive.tar.gz [file1 file2...]
tar cjvf archive.tar.bz2 [file1 file2...]

习惯上,Linux用户不会把多个文件归档在一起,而是首先将文件收集到一个唯一的目录中,然后再归档目录。因此,在用户解压归档文件时,只有一个条目出现在目录列表中。设想一下解压ZIP文件,将一个ZIP文件解压到Windows桌面,你愿意所有的文件单独出现在桌面上还是整洁优美地收集到一个单独的目录中?无论哪种方式,语法是一样的,就看要归档文件还是目录。

命令tar当然也能够执行相反的操作——解压文件,然而,由于在压缩时使用的算法不同,命令的参数也稍有不同:

tar xzvf archive.tar.gz
tar xjvf archive.tar.bz2

注意,tar.gz文件也可创建为.tgz,tar.bz2也可以创建为.tbz。其他能够tar压缩格式有:LZMA(.tar.lzma)和compress(.tar.z),但是它们都已经废弃不用了。

如果偶然发现RAR或ZIP,也可以解压缩这种文件,下载和安装Linux版本的unrar或unzip即可。它们的语法很简单:

unrar x file.rar
unzip file.zip

系统管理工具

既然你打算安装并配置Nginx,那么我们假设你就是服务器的管理员,在你的系统中建立这样一个重要的组成部分,需要充分理解Linux系统的管理概念和工具。

以超级管理员身份运行命令

正如我们在“超级帐户”部分讨论的,使用最少特权原则(the principle of least privilege)是很重要的。在这一方面,登录系统时,尽量少用root权限,如果经常使用root登录,会在许多方面令系统置于危险之中。首先,网络通信被截获,如果他们截获一个简单的用户帐户,那么潜在的电脑黑客所造成的破坏将大大减少;其次,每个人都会写错别字,如果意外键入“rm -rf / root/file.x”(注意在-rf和/之间有一个空格),这个命令“rm -rf / root/file.x”就会变成为“rm -rf /”和“rm -rf root/file.x”,后果将难以想象!它会清除根目录“/”下所有文件!因此在所有情况下,要让登录系统的用户具有适当的系统权限。

如果你以一个普通用户登录,那么如何执行管理员级别的任务或需要特定管理员权限的任务?这里有两个可能的回答,使用su和sudo。

su命令

su,是substitute user的缩写,它是一个命令,允许你使用指定的帐户来开始一个会话,如果没有指定帐户,则使用root帐户,这里将不再输入密码):

[alex@example.com ~]$ su - root
Password :
[root@example.com ~]# nano /etc/fstab

从这时开始,你就已经作为root登录了。你可以远行命令和管理任务。完成后,可以键入exit命令退出当前会话。

[root@example.com ~]# exit
exit
[alex@example.com ~]$

你可能已经注意到,su命令中用户名的前面使用了一个连字符“-”——它表示实际上是为用户建立一个shell会话,这会继承它所有的个人设置和环境变量,如果忽略连字符,则会停留在当前目录,并保护用户帐户最初登录所有的所有设置。

sudo命令

尽管它的名字非常类似于su,但sudo在一个完全不同的方式下工作。它只是使用指定的用户来执行一个命令,而不建立完整的会话,默认情况下超级用户,语法如下:

sudo nano /etc/fstab

命令su和sudo的功能上的主要不同在于:使用命令sudo执行命令时,系统提示输入自己的帐户密码。我已经能听到你的尖叫——为什么我没有root的密码却能够获取root的权限?原来在/etc/sudoers配置文件中,该文件指定了允许使用sudo的用户列表。更重要的是,指定了允许执行的命令,此外,所有用户的行为都被记录在日志文件中,包括失败的sudo尝试。

默认情况下,sudoers文件中没有用户,因此,必须先以root用户登录,然后再将指定的用户添加到/etc/sudoers文件,这个文件遵循一个严格的语法,因此,对于它可以使用一个专用的工具,visudo,其源于众所周知的vi文本编辑器,visudo检测文件的语法然后保存文件,并确保该文件没有被同时编辑。

Visudo是一种扩展功能,vi则工作在两种模式下:命令模式和插入模式。在插入模式下可以直接编辑文档,按Esc键切换到插入模式,然后进行必要的修改,例如,在文件的末尾添加一个新的sudo用户:

alex ALL=(ALL) ALL

在文件sudoers中,这种定义授予alex用户所有的命令权限。编辑完毕后,按Esc键进入命令行模式,再键入如下命令来保存修改 :w 再键入以下命令退出 :q 如果希望退出但又不想保存修改,则键入以下命令 :q! 。关于vi或visudo的更多信息,可使用man命令来了解(或者如果你熟悉行话,那就是RTFM!)

系统检查和维护

现在,你完成了管理服务器的必要条件,可以执行实际的管理任务了。第一组任务涉及系统资源,在系统发生变化时——例如安装软件包(后面的章节会有讲解)——总是要检测系统的当前状态,查看是否有足够的磁盘空间和有效的内存空间。

磁盘剩余空间

命令df用于检查挂接驱动器可用空间(见下图):

选项-h允许你以人类可读格式显示大小。应该经常检查磁盘有效空间:如果遭遇运行空间不足,应用程序可能出现任何情况(换句话说,就是难以理解的错误信息)。

磁盘使用量

如果注意到磁盘满了,但又不知道为什么,则可以求助于du命令,它特别有用。它允许你显示指定目录下第一个子目录占用的空间。

这里再次使用-h,指定以人类可讯的格式显示大小。如果不使用选项--max-depth,du会从当前目录开始递归地浏览系统中的所有文件(换句话说,就是遍历指定目录下的所有文件)。现在,便可以轻松跟踪占用系统太多存储空间的目录了。

空闲内存

命令free显示当前系统内存的使用情况。它不但显示物理内存还显示swap的状态,也包括系统缓冲状态。可以使用-m开关参数以兆字节显示或-k以千字节显示。

软件包

基本的命令行用法?有!用户和组的管理?有!系统是否有足够的内存和磁盘存储空间?有!看起来你已准备安装新的软件套件和组件。基本上有三种方式,我们将从最简单到最复杂,逐一研究它们。

软件包管理

包管理器是一个工具,方便你对系统上的软件包进行管理,让你下载并安装(软件包)、更新、卸载它们,等等。在Linux世界中,有很多种不同的安装包系统,这往往与特定的发布有关——RPM用于基于Red Hat系统的发布,APT用于基于类Debian的系统发布,简单的TGZ包用于Slackware,等等。在这里,我们只介绍前两个(即RPM和APT),它们也是我们最常用的两个。

对于使用RPM的系统,yum是使用最多的包管理工具;对于APT,则是与发布版本一起提供的apt-get工具。尽管它们的语法稍微不同,但是这两个程序的功能基本相同——指定一个包的名称,它们将在线下载该软件并且自动安装它。

下面的例子中,显示了如何使用yum的计算机上安装PHP:

[root@example.com ~]# yum install php

使用apt-get:

[root@example.com ~]# apt-get install php

所有需要的组成部分,例如库文件或其他软件都将首先下载和安装,然后再处理请求的软件包。不需要你做任何别的事情,确认即可。同样,也可以使用这两个工具的其中一个来进行升级和移除操作。

下载和手动安装软件包

请注意,目前只有有限数量的软件包可以通过这些包管理器来进行管理,这依赖于它们的仓库(repositories)“存放”的数据包种类。该仓库来自Linux发行,其使用规范通常比较严格,软件开发人员不能始终用它们来发布自己的软件。因此,有许多应用程序无法在默认的仓库中找到(但可以使用自定义仓库),这意味着你不能够使用包管理器来安装它们。

面对这种情况,有两种选择:从网上找一个安装包或者从源代码编译安装,下面详细介绍。第一个方法通常是访问包含你要安装软件的官方网站,然后找到发布的RPM安装包(或者是用于Debian系统的DEB包),再下载安装。

使用wget下载工具下载,然后再用rpm -ivh命令安装该包:

[alex@example.com ~]$ wget ftp://example2.com/mysqlclient.rpm
(Download successful)
[alex@example.com ~]$ sudo rpmivh mysqlclient.rpm

对于DEB安装包,用dpkg -i命令安装:

[alex@example.com ~]$ wget ftp://example2.com/mysqlclient.deb
(Download successful)
[alex@example.com ~]$ sudo dpkgi mysqlclient.deb

注意,这种方法不会处理依赖性,由于需要的库文件无法在系统中找到,所以应用程序可能无法正确安装。在这种情况下,只能自己安装它们(库文件)。

从源代码安装

最后一种方法,这种方法始终有效,即不管Linux的发行版本,下载应用程序的源代码并且编译它。这种方法有它自己的优势——通常可以配置大量的选项,如果你自己是个开发者,甚至还可以编辑它的源代码,从另一方面讲,它需要安装许多开发包(编译器和库等),在编译中可能会由于一些不太重要但又模糊不清的原因导致编译失败——丢失组件,没有需要的库的版本,等等。

一般做法是下载一个包含源代码的.tar.gz归档文件,然后再解压该文件,进入解压后的目录,再执行三个命令分别为configure,make和make install。在下面的例子中,我们下载一个最新版本nano,并安装它:

[alex@example.com ~]$ wget http://www.nano-editor.org/dist/v2.0/nano-
2.0.9.tar.gz
(Download successful)
[alex@example.com ~]$ tar zxvf nano-2.0.9.tar.gz
(Extraction successful)
[alex@example.com ~]$ cd nano-2.0.9
[alex@example.com nano-2.0.9]$ ./configure
(Configuration complete)
[alex@example.com nano-2.0.9]$ make
(Build successful)
[alex@example.com nano-2.0.9]$ sudo make install
(Install successful)

视软件安装的过程而定,输出的二进制可能被复制到/usr/bin目录(或者是PATH环境变量中找到的其他目录),但有时必须亲自去找。

有些应用程序需要更具体的编译命令和程序,这些描述通常在一个readme文件中说明。在编译一个应用程序之前,不应该忽视该文件,应该好好读读它。

文件和权限

基于Unix的操作系统使用一个复杂的权限机制来管理访问文件和目录。在这类系统中,目录实际上也被视为特殊文件,涉及权限的时候,它们的工作方式是一样。

理解文件权限

对于文件,有三种类型的访问:读文件、写文件和执行文件。每类访问者被定义为用户、用户组和其他用户组。权限的具体情况可以使用命令“ls -l”查看。

[alex@example.com photos]$ lsl
total 2
drwxrwxrwx 2 alex alex 4096 oct 31 11:35 Holidays in France
-rw-rw-r-- 1 alex alex    8 oct 31 09:21 photo2.jpg

第一列提供一个文件权限的特征表示,它包含如下字符:

  • 第1个字符:文件类型(-: 文件,d:目录,l:链接;或者是其他类型);
  • 第2个到第4个字符:r-读,w-写,x-执行 针对属主;
  • 第5个到第7个字符:r-读,w-写,x-执行 针对所属组;
  • 第8个到第10个字符:r-读,w-写,x-执行 针对其他用户。
目录权限

目录具有特定的属性:粘着位(sticky bit)和设置组位ID(set group ID),SGID。第1个位能够确保放在该目录中的文件只能由它们的用户(和root用户)删除。第2个位用于给目录添加sgid权限,使该目录下创建文件和文件的所属组继承该目录的所属组。

目录的权限不同于一般的文件权限:

  • x位指定是否可以进入该目录(例如使用cd);
  • r允许目录中的内容被列出(例如使用ls);
  • w位指定是否允许在该目录中新建文件(或删除已有的文件)。
八进制表示法

你肯定已经在其他的地方见过它:它的用法告诉你发变一个目录权限为0755,或者甚至是777,给定的数字实际上是八进制,以八进制的方式来表示文件和目录的权限,这种格式由3或者4个数字从0到7,这里的0表示没有权限,7表标所有的权限。

第1个数字位是一个可选的指示属性(例如粘贴位),经常不会特别指定或设置为0;

第2个数字位表示文件属主的许可权限;

第3个数字位表示文件属组的许可权限;

第4个数字位表示其他用户的许可权限。

从0到7数字值的计算方法是:第一个属性都有一个权重,所有的权重加在一起构成一个总值。权重:0表标没有任何属性;1表示“r”,2表示“w”,4表示“x”。因此,每个属性变化有自己的八进制表示,如下表所示。

权限(r,x,w)权重八进制表示
- - -0+0+00
r - -1+0+01
- w -0+2+02
r w -1+2+03
- - x0+0+44
r - x1+0+45
- w x0+2+46
r w x1+2+47

要让每一个人(文件属主、属组及其他用户)有全部的权限,则设置为rwxrwxrwx,八进制表示为:777。

改变权限

除了万能的超级用户之外,其他的用户只能改变属于自己文件的权限,修改的工具是使用众所周知的chmod工具,它有两个主要语法变种:可以指定一个完整的八进制值权限来重置文件,也可以修改特定属性。

使用一个八进制值:

[alex@example.com ~]$ chmod 777 photo2.jpg

第一个参数是一个八进制值,第二个是文件或目录的名字。

第二个语法比较复杂:

chmod who+/-what filename

第一个参数(who,+ / -,或what)由三个元素组成:

  • Who:是一个“u”(user/owner),“g”(group),“o”(others)和“a”(all)的组合,如果忽略这部分 ,新的属性就会应用到所有的用户(all);
  • + / -:如果想授予那些权限,就使用“+”;如果想剥夺那些权限,就用“-”;
  • What:是一个“r”(read),“w”(write)和“x”(execute)的组合。

下面是使用这种语法时可能使用到的一些例子:

chmod +x script.sh: 给予该脚本文件执行的权限(所有的用户均有执行的权限);

chmod go-rwx photo.jpg:除了属主外,其他人没有访问权限;

chmod a-w shopping.txt:没有人能够编辑该文件,甚至属主也不可以。

注意,使用开关参数-R可以递归修改一个目录的权限:

chmod –R g+rx photos: 该目录photos能够被属组内的任何用户访问,目录内的所有文件都可以查看。

改变用户和组的所有权

命令chown和chgrp分别允许你发变文件的属主和属组。第一个命令chown只能由超级用户执行,这显而易见是由于安全的原因。只要是该文件的属主,任何用户都可以改变自己文件的属组。

命令chown的语法如下:

chown user filename

在这里,user是这个文件filename的属主。主于chgrp:

chgrp group filename

同前面一样,group是新属组的组名,指定的文件属于新的组。还有一种使用方法,chown支持下列语法:

chown user:group filename

类似于chmod,这两个命令接受参数-R,允许你递归添加改变。以下是一些可能用到的情况:

chown alex photo.jpg:作为root用户执行,文件photo.jpg的新属主是alex;

chown –R root photos:作为root用户执行,photos目录及其目录下的所有文件和子目录都将属于root用户;

chown alex:students shopping.txt:同时改变文件的属主和属组,属主为alex,属组为students;

chgrp guests shopping.txt:将文件shopping.txt的属组改变guests;

chgrp –R applications /etc/apps:/etc/apps目录及其目录下的所有文件和子目录都将属于applications用户。

小结

最后一部份是权限,它也标志着本章的结束,概述了一个网管应该使用的命令和定期执行的任务。使用shell命令主要是记忆相关的命令名称和参数,习惯使用它之后,会变得更高效,不久以后,当你再返回使用Windows时,有时甚至会发现自己打一个命令行终端来执行简单的任务!

不管怎么样,有了所有的组成部分,就需要开始下一步——下载和安装Nginx Web服务器应用程序了。在第2章的末尾,你将有一个能够工作、并且能够载入服务器上默认网页的Web服务器。

评论 X

      友荐云推荐
      Copyright 2011-2014. YiiBook.com