严格的来讲,Linux 不算是一个操作系统,只是一个 Linux 系统中的内核 ,即计算机软件与硬件通讯之间的平台;Linux的全称是GNU/Linux,这才算是一个真正意义上的Linux系统。GNU是Richard Stallman组织的一个项目,世界各地的程序员可以变形GNU程序,同时遵循GPL协议,允许任何人任意改动。但是,修改后的程序必须遵循GPL协议。
Linux 是一个多用户多任务的操作系统,也是一款自由软件,完全兼容POSIX标准,拥有良好的用户界面,支持多种处理器架构,移植方便。
用户通过Shell与Linux内核交互。Shell是一个命令行解释工具(是一个软件),它将用户输入的命令转换为内核能够理解的语言(命令)。
Linux下,很多工作都是通过命令完成的,学好Linux,首先要掌握常用命令。
x.y:为linux的主版本号。通常y若为奇数,表示此版本为测试版,系统会有较多bug,主要用途是提供给用户测试。
zz:为次版本号。
www:代表发行号(注意,它与发行版本号无关)。
当内核功能有一个飞跃时,主版本号升级,如 Kernel2.2、2.4、2.6等。如果内核增加了少量补丁时,常常会升级次版本号,如Kernel2.6.15、2.6.20等。
一些组织或厂家将 Linux 内核与GNU软件(系统软件和工具)整合起来,并提供一些安装界面和系统设定与管理工具,这样就构成了一个发型套件,例如Ubuntu、Red Hat、Centos、Fedora、SUSE、Debian、FreeBSD等。相对于内核版本,发行套件的版本号随着发布者的不同而不同,与系统内核的版本号是相对独立的。因此把Red Hat等直接说成是Linux是不确切的,它们是Linux的发行版本,更确切地说,应该叫做"以linux为核心的操作系统软件包"。
下面是Linux体系结构的示意图:
在所有Linux版本中,都会涉及到以下几个重要概念:
内核:内核是操作系统的核心。内核直接与硬件交互,并处理大部分较低层的任务,如内存管理、进程调度、文件管理等。
Shell:Shell是一个处理用户请求的工具,它负责解释用户输入的命令,调用用户希望使用的程序。
命令和工具:日常工作中,你会用到很多系统命令和工具,如cp、mv、cat和grep等。在Linux系统中,有250多个命令,每个命令都有多个选项;第三方工具也有很多,他们也扮演着重要角色。
文件和目录:Linux系统中所有的数据都被存储到文件中,这些文件被分配到各个目录,构成文件系统。Linux的目录与Windows的文件夹是类似的概念。
login:
然后会提示你输入密码,密码也是区分大小写的。
Linux系统通过密码来保证数据和文件的安全,防止黑客破解和攻击。你可以通过以下方法来修改密码:
输入 password 命令。
输入你现在使用的密码。
输入新密码。注意密码不要过于简单,简单的密码往往会为入侵者大开便利之门。
确认密码,再输入一遍刚才的密码。
注意:输入的密码是看不到的,只会看到一个占位符(*)。
在Linux中,所有的数据都被保存在文件中,所有的文件又被分配到不同的目录;目录是一种类似树的结构,称为文件系统。
你可以使用 ls 命令来查看当前目录下的文件和目录。下面的例子,使用了 ls 命令的 -l 选项:
注意:以 d* 开头的为目录,如 uml、univ、urlspedia等;其他的都是文件。
如果你希望了解更多关于当前用户的信息,可以使用 who am i 命令,读者可以自己尝试一下。
w 命令可以看到在线用户的更多信息,读者可以自己尝试。
完成工作后,你需要退出系统,防止他人使用你的账户。
关系Linux系统可以使用下列命令:
注意:一般情况下只有超级用户和root用户(Linux系统中的最高特权用户)才有关闭系统的权限,但是给普通用户赋予相应权限也可以关闭系统。
Linux中的所有数据都被保存在文件中,所有的文件被分配到不同的目录。目录是一种类似于树的结构,称为文件系统。
在Linux中,有三种基本的文件类型:
普通文件是以字节为单位的数据流,包括文本文件、源码文件、可执行文件等。文本和二进制对Linux来说并无区别,对普通文件的解释由处理该文件的应用程序进行。
目录可以包含普通文件和特殊文件,目录相当于Windows和Mac OS中的文件夹。
有些教程中称特殊文件,是一个含义。Linux 与外部设备(例如光驱,打印机,终端,modern等)是通过一种被称为设备文件的文件来进行通信。Linux 输入输出到外部设备的方式和输入输出到一个文件的方式是相同的。Linux 和一个外部设备通讯之前,这个设备必须首先要有一个设备文件存在。
例如,每一个终端都有自己的设备文件来供 Linux 写数据(出现在终端屏幕上)和读取数据(用户通过键盘输入)。
设备文件和普通文件不一样,设备文件中并不包含任何数据。
设备文件有两种类型:字符设备文件和块设备文件。
字符设备文件以字母"c"开头。字符设备文件向设备传送数据时,一次传送一个字符。典型的通过字符传送数据的设备有终端、打印机、绘图仪、modern等。字符设备文件有时也被称为"raw"设备文件。
块设备文件以字母"b"开头。块设备文件向设备传送数据时,先从内存中的buffer中读或写数据,而不是直接传送数据到物理磁盘。磁盘和CD-ROMS既可以使用字符设备文件也可以使用块设备文件。
查看当前目录下的文件和目录可以使用 ls 命令,例如:
通过 ls 命令的 -l 选项,你可以获取更多文件信息,例如:
每一列的含义如下:
第一列:文件类型。
第二列:表示文件个数。如果是文件,那么就是1;如果是目录,那么就是该目录中文件的数目。
第三列:文件的所有者,即文件的创建者。
第四列:文件所有者所在的用户组。在Linux中,每个用户都隶属于一个用户组。
第五列:文件大小(以字节计)。
第七列:文件名或目录名。
注意:每一个目录都有一个指向它本身的子目录"." 和指向它上级目录的子目录"..",所以对于一个空目录,第二列应该为 2。
通过 ls -l 列出的文件,每一行都是以 a、d、- 或 l 开头,这些字符表示文件类型:
提示:通俗的讲软连接就是windows的快捷方式,原来文件删了,快捷方式虽然在但是不起作用了。
元字符是具有特殊含义的字符。* 和 ? 都是元字符:
* 可以匹配 0 个或多个任意字符;
? 匹配一个字符。
例如
可以显示所有以 ch 开头,以 .doc 结尾的文件:
这里,* 匹配任意一个字符。如果你希望显示所有以 .doc 结尾的文件,可以使用
隐藏文件的第一个字符为英文句号或点号(.),Linux程序(包括Shell)通常使用隐藏文件来保存配置信息。
下面是一些常见的隐藏文件:.profile:Bourne shell (sh) 初始化脚本.kshrc:Korn shell (ksh) 初始化脚本.cshrc:C shell (csh) 初始化脚本.rhosts:Remote shell (rsh) 配置文件
查看隐藏文件需要使用 ls 命令的 -a 选项:
一个点号(.)表示当前目录,两个点号(..)表示上级目录
注意:输入密码时,星号(*)作为占位符,代表你输入的字符个数。
在Linux中,可以使用 vi 编辑器创建一个文本文件,例如:
上面的命令会创建文件 filename 并打开,按下 i 键即可进入编辑模式,你可以向文件中写入内容。例如:
完成编辑后,可以按 esc 键退出编辑模式,也可以按组合键 Shift + ZZ 完全退出文件。这样,就完成了文件的创建。
vi 编辑器可以用来编辑文件。由于篇幅限制,这里仅作简单介绍,将在后面章节进行详细讲解。
如下可以打开一个名为 filename 的文件:
当文件被打开后,可以按 i 键进入编辑模式,按照自己的方式编辑文件。如果想移动光标,必须先按 esc 键退出编辑模式,然后使用下面的按键在文件内移动光标:
l 键向右移动
h 键向左移动
k 键向上移动
j 键向下移动
使用上面的按键,可以将光标快速定位到你想编辑的地方。定位好光标后,按 i 键再次进入编辑模式。编辑完成后按 esc 键退出编辑模式或者按组合键 Shift+ZZ 退出当前文件。
可以使用 cat 命令来查看文件内容,下面是一个简单的例子:
可以通过 cat 命令的 -b 选项来显示行号,例如:
可以使用 wc 命令来统计当前文件的行数、单词数和字符数,下面是一个简单的例子:
每一列的含义如下:
第一列:文件的总行数
第二列:单词数目
第三列:文件的字节数,即文件的大小
第四列:文件名
也可以一次查看多个文件的内容,例如:
可以使用 cp 命令来复制文件。cp 命令的基本语法如下:
下面的例子将会复制 filename 文件:
现在在当前目录中会多出一个和 filename 一模一样的 copyfile 文件。
重命名文件可以使用 mv 命令,语法为:
下面的例子将会把 filename 文件重命名为 newfile:
现在在当前目录下,只有一个 newfile 文件。
mv 命令其实是一个移动文件的命令,不但可以更改文件的路径,也可以更改文件名。
rm命令可以删除文件,语法为:
注意:删除文件是一种危险的行为,因为文件内可能包含有用信息,建议结合 -i 选项来使用 rm 命令。
下面的例子会彻底删除一个文件:
你也可以一次删除多个文件:
一般情况下,每个Linux程序运行时都会创建三个文件流(三个文件):
标准输入流(stdin):stdin的文件描述符为0,Linux程序默认从stdin读取数据。
标准输出流(stdout):stdout 的文件描述符为1,Linux程序默认向stdout输出数据。
标准错误流(stderr):stderr的文件描述符为2,Linux程序会向stderr流中写入错误信息。
使用下面的命令可以随时进入主目录:
这里 ~ 就表示主目录。如果你希望进入其他用户的主目录,可以使用下面的命令:
返回进入当前目录前所在的目录可以使用下面的命令:
Linux 的目录有清晰的层次结构,/ 代表根目录,所有的目录都位于 / 下面;文件在层次结构中的位置可以用路径来表示。
如果一个路径以 / 开头,就称为绝对路径;它表示当前文件与根目录的关系。举例如下:
不以 / 开头的路径称为相对路径,它表示文件与当前目录的关系。例如:
获取当前所在的目录可以使用 pwd 命令:
查看目录中的文件可以使用 ls 命令:
下面的例子将遍历 /usr/local 目录下的文件:
可以使用 mkdir 命令来创建目录,语法为:
dirname 可以为绝对路径,也可以为相对路径。例如
会在当前目录下创建 mydir 目录。又如
会在 /tmp 目录下创建 test-dir 目录。mkdir 成功创建目录后不会输出任何信息。
也可以使用 mkdir 命令同时创建多个目录,例如
会在当前目录下创建 docs 和 pub 两个目录。
使用 mkdir 命令创建目录时,如果上级目录不存在,就会报错。下面的例子中,mkdir 会输出错误信息:
为 mkdir 命令增加 -p 选项,可以一级一级创建所需要的目录,即使上级目录不存在也不会报错。例如
会创建所有不存在的上级目录。
可以使用 rmdir 命令来删除目录,例如:
注意:删除目录时请确保目录为空,不会包含其他文件或目录。
也可以使用 rmdir 命令同时删除多个目录:
如果 dirname1、dirname2、dirname3 为空,就会被删除。rmdir 成功删除目录后不会输出任何信息。
可以使用 cd 命令来改变当前所在目录,进入任何有权限的目录,语法为:
dirname 为路径,可以为相对路径,也可以为绝对路径。例如
可以进入 /usr/local/bin 目录。可以使用相对路径从这个目录进入 /usr/home/amrood 目录:
mv (move) 命令也可以用来重命名目录,语法为:
下面的例子将会把 mydir 目录重命名为 yourdir 目录:
一个点号(.)表示当前目录,两个点号(..)表示上级目录(父目录)。
ls 命令的 -a 选项可以查看所有文件,包括隐藏文件;-l 选项可以查看文件的所有信息,共有7列。例如:
为了更加安全的存储文件,Linux为不同的文件赋予了不同的权限,每个文件都拥有下面三种权限:
所有者权限:文件所有者能够进行的操作
组权限:文件所属用户组能够进行的操作
外部权限(其他权限):其他用户可以进行的操作。
第一列就包含了文件或目录的权限。
第一列的字符可以分为三组,每一组有三个,每个字符都代表不同的权限,分别为读取(r)、写入(w)和执行(x):
第一组字符(2-4)表示文件所有者的权限,-rwxr-xr-- 表示所有者拥有读取(r)、写入(w)和执行(x)的权限。
第二组字符(5-7)表示文件所属用户组的权限,-rwxr-xr-- 表示该组拥有读取(r)和执行(x)的权限,但没有写入权限。
第三组字符(8-10)表示所有其他用户的权限,rwxr-xr-- 表示其他用户只能读取(r)文件。
文件权限是Linux系统的第一道安全防线,基本的权限有读取(r)、写入(w)和执行(x):
读取:用户能够读取文件信息,查看文件内容。
写入:用户可以编辑文件,可以向文件写入内容,也可以删除文件内容。
执行:用户可以将文件作为程序来运行。
目录的访问模式和文件类似,但是稍有不同:
读取:用户可以查看目录中的文件
写入:用户可以在当前目录中删除文件或创建文件
执行:执行权限赋予用户遍历目录的权利,例如执行 cd 和 ls 命令。
可以使用 chmod (change mode) 命令来改变文件或目录的访问权限,权限可以使用符号或数字来表示。
对于初学者来说最简单的就是使用符号来改变文件或目录的权限,你可以增加(+)和删除(-)权限,也可以指定特定权限。
下面的例子将会修改 testfile 文件的权限:
也可以同时使用多个符号:
除了符号,也可以使用八进制数字来指定具体权限,如下表所示:
下面的例子,首先使用 ls -1 命令查看 testfile 文件的权限,然后使用 chmod 命令更改权限:
在Linux中,每添加一个新用户,就会为它分配一个用户ID和群组ID,上面提到的文件权限也是基于用户和群组来分配的。
有两个命令可以改变文件的所有者或群组:
chown:chown 命令是"change owner"的缩写,用来改变文件的所有者。
chgrp:chgrp 命令是"change group"的缩写,用来改变文件所在的群组。
chown 命令用来更改文件所有者,其语法如下:
user 可以是用户名或用户ID,例如
将 testfile 文件的所有者改为 amrood。
注意:超级用户 root 可以不受限制的更改文件的所有者和用户组,但是普通用户只能更改所有者是自己的文件或目录。
chgrp 命令用来改变文件所属群组,其语法为:
group可以是群组名或群组ID,例如
将文件 testfile 的群组改为 special。
在Linux中,一些程序需要特殊权限才能完成用户指定的操作。
例如,用户的密码保存在 /etc/shadow 文件中,出于安全考虑,一般用户没有读取和写入的权限。但是当我们使用passwd 命令来更改密码时,需要对 /etc/shadow 文件有写入权限。这就意味着,passwd 程序必须要给我们一些特殊权限,才可以向 /etc/shadow 文件写入内容。
Linux 通过给程序设置SUID(Set User ID)和SGID(Set Group ID)位来赋予普通用户特殊权限。当我们运行一个带有SUID位的程序时,就会继承该程序所有者的权限;如果程序不带SUID位,则会根据程序使用者的权限来运行。
SGID也是一样。一般情况下程序会根据你的组权限来运行,但是给程序设置SGID后,就会根据程序所在组的组权限运行。
如果程序设置了SUID位,就会在表示文件所有者可执行权限的位置上出现's'字母;同样,如果设置了SGID,就会在表示文件群组可执行权限的位置上出现's'字母。如下所示:
上面第一列第四个字符不是'x'或'-',而是's',说明 /usr/bin/passwd 文件设置了SUID位,这时普通用户会以root用户的权限来执行passwd程序。
注意:小写字母's'说明文件所有者有执行权限(x),大写字母'S'说明程序所有者没有执行权限(x)。
如果在表示群组权限的位置上出现SGID位,那么也仅有三类用户可以删除该目录下的文件:目录所有者、文件所有者、超级用户 root。
为一个目录设置SUID和SGID位可以使用下面的命令:
在Linux中,环境变量是一个很重要的概念。环境变量可以由系统、用户、Shell以及其他程序来设定。
变量就是一个可以被赋值的字符串,赋值范围包括数字、文本、文件名、设备以及其他类型的数据。
下面的例子,我们将为变量 TEST 赋值,然后使用 echo 命令输出:
注意:变量赋值时前面不能加 $ 符号,变量输出时必须要加 $ 前缀。退出 Shell 时,变量将消失。
Shell首先检查 /etc/profile 文件是否存在,如果存在,就读取内容,否则就跳过,但是不会报错。
读取完上面两个文件,Shell就会出现 $ 命令提示符:
出现这个提示符,就可以输入命令并调用相应的程序了。
注意:上面是Bourne Shell的初始化过程,bash 和 ksh 在初始化过程中还会检查其他文件。
/etc/profile文件包含了通用的Shell初始化信息,由Linux管理员维护,一般用户无权修改。
但是你可以修改主目录下的 .profile 文件,增加一些"私人定制"初始化信息,包括:
设置默认终端类型和外观样式;
设置 Shell 命令查找路径,即PATH变量;
设置命令提示符。
找到主目录下的 .profile 文件,使用 vi 编辑器打开并查看内容。
一般情况下,我们使用的终端是由 login 或 getty 程序设置的,可能会不符合我们的习惯。
对于没有使用过的终端,可能会比较生疏,不习惯命令的输出样式,交互起来略显吃力。所以,一般用户会将终端设置成下面的类型:
vt100 是 virtual terminate 100 的缩写。虚拟终端是一种假的终端,真正有自己的显示器和键盘的终端,会通过特殊电缆(如串口)连到计算机主机。vt100 是被绝大多数Linux系统所支持的一种虚拟终端规范,常用的还有ansi、xterm等。
在命令提示符下输入一个命令时,Shell 会根据 PATH 变量来查找该命令对应的程序,PATH变量指明了这些程序所在的路径。
一般情况下PATH变量的设置如下:
多个路径使用冒号(:)分隔。如果用户输入的命令在PATH设置的路径下没有找到,就会报错,例如:
PS1变量用来保存命令提示符,可以随意修改,如果你不习惯使用 $ 作为提示符,也可以改成其他字符。PS1变量被修改后,提示符会立即改变。
例如,把命令提示符设置成'=>':
也可以将提示信息设置成当前目录,例如:
命令提示信息包含了用户名、主机名和当前目录。
下表中的转义字符可以被用作PS1的参数,丰富命令提示符信息。
如果用户输入的命令不完整,Shell还会使用第二提示符来等待用户完成命令的输入。默认的第二命令提示符是 >,保存在 PS2 变量,可以随意修改。
下面的例子使用默认的第二命令提示符:
下面的例子通过PS2变量改变提示符:
下表列出了部分重要的环境变量,这些变量可以通过上面提到的方式修改。
下面的例子中使用了部分环境变量:
通过前面的介绍,相信你对 Linux 的命令和特性有了一个基本的认识,本节将介绍如果打印文件以及发送邮件。
如果你希望打印文本文件,最好预先处理一下,包括调整边距、设置行高、设置标题等,这样打印出来的文件更加美观,易于阅读。当然,不处理也可以打印,但是可能会比较丑陋。
大部分的Linux自带了 nroff 和 troff 两个强大的文本格式化工具,不过比较老旧,使用的人很少,有兴趣的读者可以可以自行学习,本教程不再进行深入讲解。
pr 命令用来将文本文件转换成适合打印的格式,它可以把较大的文件分割成多个页面进行打印,并为每个页面添加标题。
pr 命令的语法如下:
pr 命令仅仅改变文件在屏幕上的显示样式和打印输出样式,并不会更改文件本身。下表是 pr 命令的几个选项:
例如,food 文件包含了很多食品的名字,使用 pr 命令分成两列打印,并设置每页的标题为"Restaurants"。
首先查看文件内容:
然后使用 pr 命令打印:
lp 和 lpr 命令将文件传送到打印机进行打印。使用 pr 命令将文件格式化后就可以使用这两个命令来打印。
打印机一般由系统管理员来设置,下面的例子使用默认的打印机打印food文件:
命令成功执行会返回一个表示打印任务的ID,通过这个ID可以取消打印或者查看打印状态。
如果你希望打印多份文件,可以使用 lp 的 -nNum 选项,或者 lpr 命令的 -Num 选项。Num 是一个数字,可以随意设置。
如果系统连接了多台打印机,可以使用 lp 命令的 -dprinter 选项,或者 lpr 命令的 -Pprinter 选项来选择打印机。printer 为打印机名称。
提示:等待打印的文件会被放到打印机的的缓存队列中。
例如,使用 lpstat -o 命令查看打印机中所有等待打印的文件,包括你自己的:
lpstat -o 命令按照打印顺序输出队列中的文件。
lpq 命令显示的信息与 lpstat -o 稍有差异:
第一行为打印机的状态。如果打印机无法使用或者纸被用完,将会输出其他信息。
cancel 和 lprm 分别用来终止 lp 和 lpr 的打印请求。使用这两个命令,需要指定ID(由 lp 或 lpq 返回)或打印机名称。
例如,通过ID取消打印请求:
如果希望取消正在打印的文件,那么可以不指定ID,仅仅指定打印机名称即可:
lprm 命令用来取消当前用户的正在等待打印的文件,使用任务号作为参数可以取消指定文件,使用横线(-)作为参数可以取消所有文件。
例如,取消575号打印任务:
lprm 会返回被取消的文件名。
可以使用mail命令发送和接收邮件,语法如下:
每个选项的含义如下:
也可以通过重定向操作符 < 来发送文件:
接收邮件不需要任何参数:
有时候,我们可以把两个命令连起来使用,一个命令的输出作为另一个命令的输入,这就叫做管道 。为了建立管道,需要在两个命令之间使用竖线(|)连接。
管道是Linux进程之间一种重要的通信机制;除了管道,还有共享内存、消息队列、信号、套接字(socket) 等进程通信机制。
管道使用竖线(|)将两个命令隔开,竖线左边命令的输出就会作为竖线右边命令的输入。连续使用竖线表示第一个命令的输出会作为第二个命令的输入,第二个命令的输出又会作为第三个命令的输入,依此类推。
能够接受数据,过滤(处理或筛选)后再输出的工具,称为过滤器。
grep 是一个强大的文本搜索工具,可以使用正则表达式,并返回匹配的行,语法为:
"grep"源于 ed(Linux的一个行文本编辑器)的 g/re/p 命令,g/re/p 是"globally search for a regular expression and print all lines containing it"的缩写,意思是使用正则表达式进行全局检索,并把匹配的行打印出来。
grep 可以看做是一个过滤器,如果没有为 grep 指定要检索的文件,那么它会从标准输入设备(一般是键盘)读取;其他过滤器也是如此。
grep 命令最简单的使用就是检索包含固定字符的文本。
例如,在管道中使用 grep 命令,只允许包含指定字符的行输出到显示器:
grep 命令有很多选项:
下面我们使用正则表达式来匹配这样的行:包含字符"carol",然后包含任意数目(含零个)的其他字符,最后还要包含"Aug"。
使用 -i 选项进行不区分大小写的匹配:
sort 命令在 Linux 中非常有用,它将文件中的各行按字母或数进行排序。sort命令既可以从特定的文件,也可以从stdin获取输入。
例如,对 foot 文件的各行进行排序:
通过下面的选项可以控制排序规则:
下面的例子通过管道将 ls、grep 和 sort 命令连起来使用,过滤包含"Aug"的行,并按照文件大小排序:
上面的命令,对当前目录中八月份修改的文件按照大小排序;+4n 表示对第5列按照数字大小排序。
如果文件内容过多,全部显示会很乱,可以使用 pg 和 more 命令分页显示,每次只显示一屏。
例如,通过管道,使用more命令显示目录中的文件:
如上,一次只显示一屏文本,显示满后,停下来,并提示已显示全部内容的百分比,按空格键(space)可以查看下一屏,按 b 键可以查看上一屏。
当我们运行程序时,Linux会为程序创建一个特殊的环境,该环境包含程序运行需要的所有资源,以保证程序能够独立运行,不受其他程序的干扰。这个特殊的环境就称为进程。
每个 Linux 命令都与系统中的程序对应,输入命令,Linux 就会创建一个新的进程。例如使用 ls 命令遍历目录中的文件时,就创建了一个进程。
简而言之,进程就是程序的实例。
系统通过一个五位数字跟踪程序的运行状态,这个数字称为 pid 或进程ID。每个进程都拥有唯一的 pid。
理论上,五位数字是有限的,当数字被用完时,下一个 pid 就会重新开始,所以 pid 最终会重复。但是,两个 pid 一样的进程不能同时存在,因为Linux会使用 pid 来跟踪程序的运行状态。
有两种方式来创建进程:前台进程和后台进程。
默认情况下,用户创建的进程都是前台进程;前台进程从键盘读取数据,并把处理结果输出到显示器。
我们可以看到前台进程的运行过程。例如,使用 ls 命令来遍历当前目录下的文件:
这个程序就运行在前台,它会直接把结果输出到显示器。如果 ls 命令需要数据(实际上不需要),那么它会等待用户从键盘输入。
后台进程与键盘没有必然的关系。当然,后台进程也可能会等待键盘输入。
后台进程的优点是不必等待程序运行结束就可以输入其他命令。
创建后台进程最简单的方式就是在命令的末尾加 &,例如:
如果 ls 命令需要输入(实际上不需要),那么它会暂停,直到用户把它调到前台并从键盘输入数据才会继续运行。
可以使用 ps 命令查看进程的运行状态,包括后台进程,例如:
还可以结合 -f 选项查看更多信息,f 是 full 的缩写,例如:
每列的含义如下:
ps 命令还有其他一些选项:
当进程运行在前台时,可以通过 kill 命令或 Ctrl+C 组合键来结束进程。
如果进程运行在后台,那么首先要通过 ps 命令来获取进程ID,然后使用 kill 命令"杀死"进程,例如:
如上所示,kill 命令终结了 first_one 进程。
如果进程忽略 kill 命令,那么可以通过 kill -9 来结束:
每个 Linux 进程会包含两个进程ID:当前进程ID(pid)和父进程ID(ppid)。可以暂时认为所有的进程都有父进程。
由用户运行的大部分命令都将 Shell 作为父进程,使用 ps -f 命令可以查看当前进程ID和父进程ID。
正常情况下,子进程被终止时会通过 SIGCHLD 信号通知父进程,父进程可以做一些清理工作或者重新启动一个新的进程。但在某些情况下,父进程会在子进程之前被终止,那么这些子进程就没有了"父亲",被称为孤儿进程 。
init 进程会成为所有孤儿进程的父进程。init 的 pid 为1,是Linux系统的第一个进程,也是所有进程的父进程。
如果一个进程被终止了,但是使用 ps 命令仍然可以查看该进程,并且状态为 Z,那么这就是一个僵尸进程。僵尸进程虽然被终止了,但是仍然存在于进程列表中。一般僵尸进程很难杀掉,你可以先杀死他们的父进程,让他们变成孤儿进程,init 进程会自动清理僵尸进程。
常驻进程一般是系统级进程,以 root 权限运行在后台,可以处理其他进程的请求。
常驻进程没有终端,不能访问 /dev/tty 文件,如果使用 ps -ef 查看该进程,tty 这一列会显示问号(?)。
top 命令是一个很有用的工具,它可以动态显示正在运行的进程,还可以按照指定条件对进程进行排序,与Windows的任务管理器类似。
top 命令可以显示进程的很多信息,包括物理内存、虚拟内存、CPU使用率、平均负载以及繁忙的进程等。例如:
任务(task)是最抽象的,是一个一般性的术语,指由软件完成的一个活动。一个任务既可以是一个进程,也可以是多个进程。简而言之,它指的是一系列共同达到某一目的的操作。例如,读取数据并将数据放入内存中。这个任务可以由一个进程来实现,也可以由多个进程来实现。 每个任务都有一个数字表示的任务号。
进程(process)常常被定义为程序的执行。可以把一个进程看成是一个独立的程序,在内存中有其完备的数据空间和代码空间。一个进程所拥有的数据和变量只属于它自己。
jobs 命令可以用来查看系统中正在运行的任务,包括后台运行的任务。该命令可以显示任务号及其对应的进程ID。一个任务可以对应于一个或者多个进程号。
jobs 命令的 -l 选项可以查看当前任务包含的进程ID:
其中,第一列表示任务号,第二列表示任务对应的进程ID,第三列表示任务的运行状态,第四列表示启动任务的命令。
fg 命令可以将后台任务调到前台,语法为:
jobnumber 是通过 jobs 命令获取的后台任务的的序号,注意不是pid。如果后台只有一个任务,可以不指定 jobnumber。
bg 命令可以将后台暂停的任务,调到前台继续运行,语法为:
jobnumber 同样是通过 jobs 命令获取的后台任务的的序号,注意不是pid。如果前台只有一个任务,可以不指定 jobnumber。
如果希望将当前任务转移到后台,可以先 Ctrl+z 暂停任务,再使用 bg 命令。任务转移到后台可以空出终端,继续输入其他命令。
现在是一个互联网的时代,你不可避免的要和其他用户进行远程交流,连接到远程主机。
ping 命令会向网络上的主机发送应答请求,根据响应信息可以判断远程主机是否可用。
ping 命令的语法:
如果网络畅通,很快就可以看到响应信息。
例如,检测是否可以连接到谷歌的主机:
如果主机没有响应,可以看到类似下面的信息:
ftp 是 File Transfer Protocol 的缩写,称为文件传输协议。通过 ftp 工具,能够将文件上传到远程服务器,也可以从远程服务器下载文件。
ftp 工具有自己的命令(类似Linux命令),可以:
查看目录,遍历目录下的文件;
上传或下载文件,包括文本文件、二进制文件等。
ftp 命令的用法如下:
接下来会提示你输入用户名和密码,验证成功后会进入主目录,然后就可以使用 ftp 工具的命令进行操作了。
注意,所有的上传和下载都是针对本地主机和远程主机的当前目录,如果你希望上传指定目录下的文件,首先要 cd 到该目录,然后才能上传。
ftp 工具使用举例:
一旦连接到了远程计算机,就可以在上面进行各种操作了,例如:
finger 可以让我们查看本地主机或远程主机上的用户信息。有些系统为了安全会禁用 finger 命令。
例如,查看本机在线用户:
查看本机指定用户的信息:
查看远程主机上的在线用户:
查看远程主机上某个用户的信息:
Linux下的文本编辑器有很多种,vi 是最常用的,也是各版本Linux的标配。注意,vi 仅仅是一个文本编辑器,可以给字符着色,可以自动补全,但是不像 Windows 下的 word 有排版功能。
vi 是十年磨一剑的产品,虽然命令繁多,并且大多数功能都是依靠键盘输入来完成,但是一旦你熟悉后,会发现 vi 的功能和效率是其他图形界面编辑器无法比拟的。
Vim 是 V i improved 的缩写,是 vi 的改进版。在Linux中,vi 被认为是事实上的标准编辑器,因为:
所有版本的 Linux 都带有 vi 编辑器;
占用资源少;
与 ed、ex 等其他编辑器相比,vi 对用户更加友好。
你可以使用 vi 编辑器编辑现有的文件,也可以创建一个新文件,还能以只读模式打开文本文件。
可以通过以下方式进入 vi 编辑器:
例如,使用 vi 编辑器创建一个新文件并打开:
竖线(|)代表光标的位置;波浪号(~)代表该行没有任何内容。如果没有 ~,也看不到任何内容,那说明这一行肯定是有空白字符(空格、tab 缩进、换行符等)或不可见字符。
进一步了解 vi 之前先来了解一下 vi 的工作模式,vi 有三种工作模式:
由Shell进入vi编辑器时,首先进入普通模式。在普通模式下,从键盘输入任何字符都被当作命令来解释。普通模式下没有任何提示符,输入命令后立即执行,不需要回车,而且输入的字符不会在屏幕上显示出来。
普通模式下可以执行命令、保存文件、移动光标、粘贴复制等。
编辑模式主要用于文本的编辑。该模式下用户输入的任何字符都被作为文件的内容保存起来,并在屏幕上显示出来。
命令模式下,用户可以对文件进行一些高级处理。尽管普通模式下的命令可以完成很多功能,但要执行一些如字符串查找、替换、显示行号等操作还是必须要进入命令模式。
注意:有些教程中称有两种工作模式,是把命令模式合并到普通模式。
工作模式切换:
在普通模式下输入 i(插入)、c(修改)、o(另起一行) 命令时进入编辑模式;按 esc 键退回到普通模式。
在普通模式下输入冒号(:)可以进入命令模式。输入完命令按回车,命令执行完后会自动退回普通模式。
提示:如果不确定当前处于哪种模式,按两次 Esc 键将回到普通模式。
一般在命令模式下退出 vi 编辑器。
退出之前,你也可以在 w 命令后面指定一个文件名,将文件另存为新文件,例如:
将当前文件另存为 filename2。
注意:vi 编辑文件时,用户的操作都是基于缓冲区中的副本进行的。如果退出时没有保存到磁盘,则缓冲区中的内容就会被丢失。
为了不影响文件内容,必须在普通模式(按两次 Esc 键)下移动光标。使用下表中的命令每次可以移动一个字符:
两点提醒:
vi 是区分大小写的,输入命令时注意不要锁定大写。
可以在命令前边添加一个数字作为前缀,例如,2j 将光标向下移动两行。
当然,还有很多其他命令来移动光标,不过记住,一定要在普通模式(按两次 Esc 键)下。
有一些控制命令可以与 Ctrl 键组合使用,如下:
切换到编辑模式下才能编辑文件。有很多命令可以从普通模式切换到编辑模式,如下所示:
下面的命令,可以删除文件中的字符或行:
可以在命令前面添加一个数字前缀,表示重复操作的次数,例如,2x 表示连续两次删除光标下的字符,2dd 表示连续两次删除光标所在的行。
建议各位读者多加练习上面的命令,再进一步深入学习。
如果你希望对字符、单词或行进行修改,可以使用下面的命令:
vi 中的复制粘贴命令:
下面的一些命令虽然看起来有些古怪,但是会让你的工作更有效率,如果你是 vi 重度用户,就了解一下吧。
如果希望进行全文件搜索,可以在普通模式(按两次 Esc 键)下输入 / 命令,这时状态栏(最后一行)出现"/"并提示输入要查找的字符串,回车即可。
/ 命令是向下查找,如果希望向上查找,可以使用 ? 命令。
这时,输入 n 命令可以按相同的方向继续查找,输入 N 命令可以按相反的方向继续查找。
搜索的字符串中可以包含一些有特殊含义的字符,如果希望搜索这些字符本身,需要在前面加反斜杠(\)。
如果希望搜索某行中的单个字符,可以使用 f 或 F 命令,f 向上搜索,F 向下搜索,并且会把光标定位到匹配的字符。
也可以使用 t 或 T 命令:t 命令向上搜索,并把光标定位到匹配字符的前面;T 命令向下搜索,并把光标定位到匹配字符的后面。
set 命令可以对 vi 编辑器进行一些设置。使用 set 命令需要进入命令模式。
切换到命令模式,再输入 ! 命令即可运行 Linux 命令。
例如,保存文件前,如果希望查看该文件是否存在,那么输入
即可列出当前目录下的文件。
按任意键回到 vi 编辑器。
切换到命令模式,再输入 s/ 命令即可对文本进行替换。语法为:
search 为检索的文本,replace 为要替换的文本,g 表示全局替换。
vi 编辑器的使用讲解完毕,但是请记住下面几点:
输入冒号(:)进入命令模式,按两次 Esc 键进入普通模式。
命令大小写的含义是不一样的。
必须在编辑模式下才能输入内容。
文件系统就是分区或磁盘上的所有文件的逻辑集合。
文件系统不仅包含着文件中的数据而且还有文件系统的结构,所有Linux 用户和程序看到的文件、目录、软连接及文件保护信息等都存储在其中。
不同Linux发行版本之间的文件系统差别很少,主要表现在系统管理的特色工具以及软件包管理方式的不同,文件目录结构基本上都是一样的。
文件系统有多种类型,如:
ext2 : 早期linux中常用的文件系统;
ext3 : ext2的升级版,带日志功能;
RAMFS : 内存文件系统,速度很快;
iso9660:光盘或光盘镜像;
NFS : 网络文件系统,由SUN发明,主要用于远程文件共享;
MS-DOS : MS-DOS文件系统;
FAT : Windows XP 操作系统采用的文件系统;
NTFS : Windows NT/XP 操作系统采用的文件系统。
文件系统位于磁盘分区中;一个硬盘可以有多个分区,也可以只有一个分区;一个分区只能包含一个文件系统。
Linux文件系统与Windows有较大的差别。Windows的文件结构是多个并列的树状结构,最顶部的是不同的磁盘(分区),如 C、D、E、F等。
Linux的文件结构是单个的树状结构,根目录是"/",其他目录都要位于根目录下。
每次安装系统的时候我们都会进行分区,Linux下磁盘分区和目录的关系如下:
任何一个分区都必须对应到某个目录上,才能进行读写操作,称为"挂载"。
被挂载的目录可以是根目录,也可以是其他二级、三级目录,任何目录都可以是挂载点。
目录是逻辑上的区分。分区是物理上的区分。
根目录是所有Linux的文件和目录所在的地方,需要挂载上一个磁盘分区。
为什么要分区,如何分区?
可以把不同资料,分别放入不同分区中管理,降低风险。
大硬盘搜索范围大,效率低。
/home、/var、/usr/local 经常是单独分区,因为经常会操作,容易产生碎片。
为了便于定位和查找,Linux中的每个目录一般都存放特定类型的文件,下表列出了各种Linux发行版本的常见目录:
你可以通过下面的命令来管理文件:
管理磁盘分区时经常会使用 df (disk free) 命令,df -k 命令可以用来查看磁盘空间的使用情况(以千字节计),例如:
每一列的含义如下:
某些目录(例如 /devices)的 kbytes、used、avail 列为0,use列为0%,这些都是特殊(或虚拟)文件系统,即使位于根目录下,也不占用硬盘空间。
你可以结合 -h (human readable) 选项将输出信息格式化,让人更易阅读。
du (disk usage) 命令可以用来查看特定目录的空间使用情况。
du 命令会显示每个目录所占用数据块。根据系统的不同,一个数据块可能是 512 字节或 1024 字节。举例如下:
结合 -h 选项可以让信息显示的更加清晰:
挂载是指将一个硬件设备(例如硬盘、U盘、光盘等)对应到一个已存在的目录上。 若要访问设备中的文件,必须将文件挂载到一个已存在的目录上, 然后通过访问这个目录来访问存储设备。
这样就为用户提供了统一的接口,屏蔽了硬件设备的细节。Linux将所有的硬件设备看做文件,对硬件设备的操作等同于对文件的操作。
注意:挂载目录可以不为空,但挂载后这个目录下以前的内容将不可用。
需要知道的是,光盘、软盘、其他操作系统使用的文件系统的格式与linux使用的文件系统格式是不一样的,挂载需要确认Linux是否支持所要挂载的文件系统格式。
查看当前系统所挂载的硬件设备可以使用 mount 命令:
一般约定,/mnt 为临时挂载目录,例如挂载CD-ROM、远程网络设备、软盘等。
也可以通过mount命令来挂载文件系统,语法为:
例如:
将 CD-ROM 挂载到 /mnt/cdrom 目录。
注意:file_system_type用来指定文件系统类型,通常可以不指定,Linux会自动正确选择文件系统类型。
挂载文件系统后,就可以通过 cd、cat 等命令来操作对应文件。
可以通过 umount 命令来卸载文件系统。例如,卸载 cdrom:
不过,大部分现代的Linux系统都有自动挂载卸载功能,unmount 命令较少用到。
用户和群组配额可以让管理员为每个用户或群组分配固定的磁盘空间。
管理员有两种方式来分配磁盘空间:
软限制:如果用户超过指定的空间,会有一个宽限期,等待用户释放空间。
硬限制:没有宽限期,超出指定空间立即禁止操作。
下面的命令可以用来管理配额:
大部分的Linux文件系统(如ext2、ext3)规定,一个文件由目录项、inode和数据块组成:
目录项:包括文件名和inode节点号。
Inode:又称文件索引节点,包含文件的基础信息以及数据块的指针。
数据块:包含文件的具体内容。
理解inode,要从文件储存说起。文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector),每个扇区储存512字节(相当于0.5KB)。
操作系统读取硬盘的时候,不会一个扇区一个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。
文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。
inode包含文件的元信息,具体来说有以下内容:
文件的字节数。
文件拥有者的User ID。
文件的Group ID。
文件的读、写、执行权限。
链接数,即有多少文件名指向这个inode。
文件数据block的位置。
可以用stat命令,查看某个文件的inode信息:
总之,除了文件名以外的所有文件信息,都存在inode之中。至于为什么没有文件名,下文会有详细解释。
当查看某个文件时,会先从inode表中查出文件属性及数据存放点,再从数据块中读取数据。
inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。
每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。
查看每个硬盘分区的inode总数和已经使用的数量,可以使用df -i 命令。
查看每个inode节点的大小,可以用如下命令:
由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。
每个inode都有一个号码,操作系统用inode号码来识别不同的文件。
这里值得重复一遍,Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。
使用ls -i命令,可以看到文件名对应的inode号码,例如:
Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。
目录文件的结构非常简单,就是一系列目录项(dirent)的列表。每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。
ls命令只列出目录文件中的所有文件名:
ls -i命令列出整个目录文件,即文件名和inode号码:
如果要查看文件的详细信息,就必须根据inode号码,访问inode节点,读取信息。ls -l命令列出文件的详细信息。
一般情况下,文件名和inode号码是"一一对应"关系,每个inode号码对应一个文件名。但是,Linux系统允许,多个文件名指向同一个inode号码。这意味着,可以用不同的文件名访问同样的内容;对文件内容进行修改,会影响到所有文件名;但是,删除一个文件名,不影响另一个文件名的访问。这种情况就被称为"硬链接"(hard link)。
ln命令可以创建硬链接,语法为:
运行上面这条命令以后,源文件与目标文件的inode号码相同,都指向同一个inode。inode信息中有一项叫做"链接数",记录指向该inode的文件名总数,这时就会增加1。反过来,删除一个文件名,就会使得inode节点中的"链接数"减1。当这个值减到0,表明没有文件名指向这个inode,系统就会回收这个inode号码,以及其所对应block区域。
这里顺便说一下目录文件的"链接数"。创建目录时,默认会生成两个目录项:"."和".."。前者的inode号码就是当前目录的inode号码,等同于当前目录的"硬链接";后者的inode号码就是当前目录的父目录的inode号码,等同于父目录的"硬链接"。所以,任何一个目录的"硬链接"总数,总是等于2加上它的子目录总数(含隐藏目录),这里的2是父目录对其的"硬链接"和当前目录下的".硬链接"。
除了硬链接以外,还有一种特殊情况。文件A和文件B的inode号码虽然不一样,但是文件A的内容是文件B的路径。读取文件A时,系统会自动将访问者导向文件B。因此,无论打开哪一个文件,最终读取的都是文件B。这时,文件A就称为文件B的"软链接"(soft link)或者"符号链接(symbolic link)。
这意味着,文件A依赖于文件B而存在,如果删除了文件B,打开文件A就会报错:"No such file or directory"。这是软链接与硬链接最大的不同:文件A指向文件B的文件名,而不是文件B的inode号码,文件B的inode"链接数"不会因此发生变化。
ln -s命令可以创建软链接,语法为:
在Linux中,有三种用户:
Root 用户:也称为超级用户,对系统拥有完全的控制权限。超级用户可以不受限制的运行任何命令。Root 用户可以看做是系统管理员。
系统用户:系统用户是Linux运行某些程序所必须的用户,例如 mail 用户、sshd 用户等。系统用户通常为系统功能所必须的,不建议修改这些用户。
普通用户:一般用户都是普通用户,这些用户对系统文件的访问受限,不能执行全部Linux命令。
Linux支持用户组,用户组就是具有相同特征的用户的集合。一个组可以包含多个用户,每个用户也可以属于不同的组。用户组在Linux中扮演着重要的角色,方便管理员对用户进行集中管理。
与用户和组有关的系统文件:
来看一下/etc/passwd文件的结构:
对每个字段的说明:
下面是一些常用的管理用户和组的命令:
添加用户时,可以将用户添加到现有的用户组,或者创建一个新的用户组。可以在 /etc/groups 文件中看到所有的用户组信息。
默认的用户组通常用来管理系统用户,不建议将普通用户添加到这些用户组。使用groupadd命令创建用户组的语法为:
每个选项的含义如下:
如果不指定选项,系统将使用默认值。例如创建一个 developers 用户组:
groupmod命令可以用来修改用户组,语法为:
例如,将用户组 developers_2 重命名为 developer:
将developer用户组的ID改为545:
通过groupdel命令可以删除用户组。例如,删除developer组:
添加用户可以使用useradd命令,语法为:
每个选项的含义如下:
如果不指定任何选项,系统将使用默认值。useradd 命令将会修改 /etc/passwd、/etc/shadow、and /etc/group 三个文件,并创建用户主目录。
下面的例子将会添加用户 mcmohd,并设置主目录为 /home/mcmohd,用户组为 developers,默认 Shell 为 Korn Shell:
注意:添加用户前请确认 developers 用户组存在。
用户被创建后,可以使用 passwd 命令来设置密码,例如:
注意:如果你是管理员,输入 $ passwd username 可以修改你所管理的用户的密码;否则只能修改你自己的密码(不需要提供username)。
usermod 命令可以修改现有用户的信息。usermod 命令的选项和 useradd 相同,不过可以增加 -l 选项来更改用户名。
下面的例子将用户 mcmohd 的用户名修改为 mcmohd20,主目录修改为 /home/mcmohd20:
userdel 命令可以用来删除现有用户。userdel 是一个危险的命令,请谨慎使用。
userdel 命令仅有一个选项 -r,用来删除用户主目录和本地邮件。例如,删除用户 mcmohd20:
为了便于恢复被误删的用户,可以忽略 -r 选项,保留用户主目录,之后确认无误可以随时删除主目录。
这篇教程的目的是向大家介绍一些免费的系统性能分析工具(命令),使用这些工具可以监控系统资源使用情况,便于发现性能瓶颈。
系统的整体性能取决于各种资源的平衡,类似木桶理论,某种资源的耗尽会严重阻碍系统的性能。
影响系统性能的主要因素有:
下面的命令可以用来监控系统性能并作出相应调整:
常用命令组合:
vmstat、sar、mpstat检测是否存在CPU瓶颈;
vmstat、free检测是否存在内存瓶颈;
iostat检测是否存在磁盘I/O瓶颈;
netstat检测是否存在网络I/O瓶颈。
Linux系统拥有非常灵活和强大的日志功能,可以保存几乎所有的操作记录,并可以从中检索出我们需要的信息。
Linux系统内核和许多程序会产生各种错误信息、警告信息和其他的提示信息,这些信息对管理员了解系统的运行状态是非常有用的,所以应该把它们写到日志文件中去。完成这个过程的程序就是syslog。syslog可以根据日志的类别和优先级将日志保存到不同的文件中。例如,为了方便查阅,可以把内核信息与其他信息分开,单独保存到一个独立的日志文件中。默认配置下,日志文件通常都保存在"/var/log"目录下。
下面是常见的日志类型,但并不是所有的Linux发行版都包含这些类型:
常见的日志优先级请见下标:
所有的系统应用都会在 /var/log 目录下创建日志文件,或创建子目录再创建日志文件。例如:
第一列为日志类型和日志优先级的组合,每个类型和优先级的组合称为一个选择器;后面一列为保存日志的文件、服务器,或输出日志的终端。syslog 进程根据选择器决定如何操作日志。
对配置文件的几点说明:
星号(*)表示所有,例如 *.debug 表示所有类型的调试信息,kern.* 表示由内核产生的所有消息。
可以使用逗号(,)分隔多个日志类型,使用分号(;)分隔多个选择器。
对日志的操作包括:
将日志输出到文件,例如 /var/log/maillog 或 /dev/console。
将消息发送给用户,多个用户用逗号(,)分隔,例如 root, amrood。
通过管道将消息发送给用户程序,注意程序要放在管道符(|)后面。
logger 是Shell命令,可以通过该命令使用 syslog 的系统日志模块,还可以从命令行直接向系统日志文件写入一行信息。
logger命令的语法为:
每个选项的含义如下:
例如,将ping命令的结果写入日志:
ping命令的结果成功输出到 /var/log/userlog 文件。
-i:在每行都记录进程ID;
-t logger_test:每行记录都加上"logger_test"这个标签;
日志转储也叫日志回卷或日志轮转。Linux中的日志通常增长很快,会占用大量硬盘空间,需要在日志文件达到指定大小时分开存储。
syslog 只负责接收日志并保存到相应的文件,但不会对日志文件进行管理,因此经常会造成日志文件过大,尤其是WEB服务器,轻易就能超过1G,给检索带来困难。
大多数Linux发行版使用 logrotate 或 newsyslog 对日志进行管理。logrotate 程序不但可以压缩日志文件,减少存储空间,还可以将日志发送到指定 E-mail,方便管理员及时查看日志。
例如,规定邮件日志 /var/log/maillog 超过1G时转储,每周一次,那么每隔一周 logrotate 进程就会检查 /var/log/maillog 文件的大小:
如果没有超过1G,不进行任何操作。
如果在1G~2G之间,就会创建新文件 /var/log/maillog.1,并将多出的1G日志转移到该文件,以给 /var/log/maillog 文件瘦身。
如果在2G~3G之间,会继续创建新文件 /var/log/maillog.2,并将 /var/log/maillog.1 的内容转移到该文件,将 /var/log/maillog 的内容转移到 /var/log/maillog.1,以保持 /var/log/maillog 文件不超过1G。
可以看到,每次转存都会创建一个新文件(如果不存在),命名格式为日志文件名加一个数字(从1开始自动增长),以保持当前日志文件和转存后的日志文件不超过指定大小。
可以通过 cat 命令查看它的内容:
注意:include 允许管理员把多个分散的文件集中到一个,类似于C语言的 #include,将其他文件的内容包含进当前文件。
logrotate 也可以作为命令直接运行来修改配置文件。
信号(signal)是Linux进程间通信的一种机制,全称为软中断信号,也被称为软中断。信号本质上是在软件层次上对硬件中断机制的一种模拟。
与其他进程间通信方式(例如管道、共享内存等)相比,信号所能传递的信息比较粗糙,只是一个整数。但正是由于传递的信息量少,信号也便于管理和使用,可以用于系统管理相关的任务,例如通知进程终结、中止或者恢复等。
每种信号用一个整型常量宏表示,以SIG开头,比如SIGCHLD、SIGINT等,它们在系统头文件<signal.h>中定义。
信号由内核(kernel)管理,产生方式多种多样:
可以由内核自身产生,比如出现硬件错误、内存读取错误,分母为0的除法等,内核需要通知相应进程。
也可以由其他进程产生并发送给内核,再由内核传递给目标进程。
信号传递的过程:
内核中针对每一个进程都有一个表来保存信号。
当内核需要将信号传递给某个进程时,就在该进程对应的表中写入信号,这样就生成了信号。
当该进程由用户态陷入内核态,再次切换到用户态之前,会查看表中的信号。如果有信号,进程就会首先执行信号对应的操作,此时叫做执行信号。
我们可以编写代码,让进程阻塞(block)某些信号,也就是让这些信号始终处于等待的状态,直到进程取消阻塞(unblock)或者忽略信号。
下表列出了一些常见信号:
通过 kill -l 命令可以查看系统支持的所有信号:
上面仅是一个演示,不同的Linux发行版支持的信号可能不同。
每种信号都会有一个默认动作。默认动作就是脚本或程序接收到该信号所做出的默认操作。常见的默认动作有终止进程、退出程序、忽略信号、重启暂停的进程等,上表中也对部分默认动作进行了说明。
有多种方式可以向程序或脚本发送信号,例如按下<Ctrl+C>组合键会发送SIGINT信号,终止当前进程。
还可以通过 kill 命令发送信号,语法为:
signal为要发送的信号,可以是信号名称或数字;pid为接收信号的进程ID。例如:
将SIGHUP信号发送给进程ID为1001的程序,程序会终止执行。
又如,强制杀死ID为1001的进程:
通常情况下,直接终止进程并不是我们所希望的。例如,按下<Ctrl+C>,进程被立即终止,不会清理创建的临时文件,带来系统垃圾,也不会保存正在进行的工作,导致需要重做。
可以通过编程来捕获这些信号,当终止信号出现时,可以先进行清场和保存处理,再退出程序。
用户程序可以通过C/C++等代码捕获信号,这将在Linux C编程中进行讲解,这里仅介绍如果通过Linux命令捕获信号。
通过 trap 命令就可以捕获信号,语法为:
commands为Linux系统命令或用户自定义命令;signals为要捕获的信号,可以为信号名称或数字。
捕获到信号后,可以有三种处理:
执行一段脚本来做一些处理工作,例如清理临时文件;
接受(恢复)信号的默认操作;
忽略当前信号。
脚本捕获到终止信号后一个常见的动作就是清理临时文件。例如:
注意:exit 命令是必须的,否则脚本捕获到信号后会继续执行而不是退出。
修改上面的脚本,使接收到 SIGHUP 时进行同样的操作:
几点注意:
如果执行多个命令,需要将命令用引号包围;
只有脚本执行到 trap 命令时才会捕获信号;
再次接收到信号时还会执行同样的操作。
上面的脚本,执行到 trap 命令时就会替换 WORKDIR 和 $$ 的值。如果希望接收到 SIGHUP 或 SIGINT 信号时再替换其值,那么可以将命令放在单引号内,例如:
如果 trap 命令的 commands 为空,将会忽略接收到的信号,即不做任何处理,也不执行默认动作。例如:
也可以同时忽略多个信号:
注意:必须被引号包围,不能写成下面的形式:
如果希望改变信号的默认动作后再次恢复默认动作,那么省略 trap 命令的 commands 即可,例如: