一次性付费进群,长期免费索取教程,没有付费教程。 进微信群回复公众号:微信群;QQ群:460500587 教程列表 见微信公众号底部菜单 | 本文底部有推荐书籍 ![]() 微信公众号:计算机与网络安全 ID:Computer-network Linux是IT领域中尽人皆知的著名开源操作系统,其设计体系完善、运行性能突出,受到全球各地技术企业与技术爱好者的青睐。Linux继承了UNIX的设计思想,在全球的服务器、PC市场中得到了广泛应用,并形成了Red Hat和Debian两大版本家族以及Ubuntu、CentOS、Mint、Kali Linux等诸多不同版本。同时,鉴于良好的结构设计以及源码级的可定制、可扩展特性,面向物联网和嵌入式装备的Linux演化版本也不断涌现,Android、MontaVista、Clinux等已占据了嵌入式操作系统市场的半壁江山。优秀的设计思想、开放的源码体系、多元的产品形态以及巨大的应用市场使Linux在诞生后的近30年里受到了政府、企业、高校等各界的持续关注与追捧。 1、与众不同 Linux是一款免费的操作系统,这意味着在任何需要的时间和需要的地点它都要比其他操作系统更容易安装。不用担心购买网站授权并受到数字版权管理(Digital Rights Management)的制约,这对所有类型的组装机器以及服务器配置的测试变得更加直接。 Linux让开展各种实际有用且具有创造性的事情成为可能。例如,可以在一个U盘上装载Linux的自生系统引导映像(live boot image),启动一台硬盘已经崩溃的计算机,之后查找并解决该问题。或者,因为Linux是一个真正的多用户操作系统,它具有非常好的私密性和稳定性,整个团队可以同时从本地或远程登录进行工作。 Linux的构建采用了一些与UNIX操作系统相同的技术,并带有大多数与深度成熟的UNIX操作系统相一致的工具。这极大地增加了稳定性与安全性。Linux的发行版还提供了复杂的软件包管理系统,可以可靠地安装和维护每一个在线资源库中成千上万的免费软件应用。 Linux不仅是免费的,更是开源的(open source),这意味着任何人都可以获得其代码并根据自己的需求进行修改。事实上,这已经孵化出专属Linux各发行版的巨大生态系统。一个发行版(distribution,有时缩写为distro)是一个定制的软件包,它将Linux内核以及用户计算机Linux运行版的安装工具一起发布。表1给出了一个不完整的发行版列表,以对可用的Linux类型进行说明。 ![]() 表1 部分常用的Linux发行版 线上有大量活跃的社区,正是基于社区的资源真正地让Linux变得如此强大。 2、基础必备 (1)Linux文件系统 人们常说Linux中的一切都是通过纯文本文件工作的,因此,从理解Linux文件系统开始可能是最有意义的事情。但在开始学习Linux之前,首先需要弄明白文件系统(file system)是什么?可以将文件系统看作在具有确定硬盘位置的单个文件和文件组之间创建了显式连接的一个数据表(或者一个索引,index)。图1能够帮助您形象地查看分布在硬盘中的数据如何以目录结构的方式呈现给系统用户。 ![]() 图1 存储设备上的原始数据可以被操作系统形象地表示为有组织的目录层次结构 为什么需要索引?因为像硬盘或USB设备这样的数字存储设备并不能被划分为用于组织文件夹(folder,或目录,directory)的物理分区。一个特定的文件可能驻留在实际物理介质的某个位置,其距离另一个大约在几分钟或几秒钟之前创建的相同文件很远,而且,一个文件的所有块可能不是连续的。不仅如此,一个文件在硬盘上的物理位置也无须一直固定。 如果希望数据是可靠获取的,将需要某种类型的索引始终指向所需要的资源。文件系统使用这样的索引来呈现单个硬盘分块(即分区,partition)中的一组被组织起来的目录和文件。 如果有时需要更加深入地了解该主题,了解当前最为常用的Linux文件系统——ext4将很有用。当然,Linux也可以在使用如FAT32和NTFS等其他文件系统格式化过的存储驱动器上运行。 硬盘分区中的所有文件都被保存在根目录(root directory,用正斜杠符号“/”表示)下的目录中。这些目录的组织方式主要由UNIX文件系统层次结构标准(Filesystem Hierarchy Standard,FHS)决定。无论是使用Linux发行版、UNIX或者甚至是macOS,都将看到非常多相同的基础结构。图2给出了一些最为常用的、顶层的目录。 ![]() 图2 UNIX FHS定义的公共顶层目录 顶层目录,即直接位于根目录下的那些目录——包括目录/etc/,其中包含定义个体程序和服务功能的配置文件,以及目录/var/,其中包含属于系统或各个应用的、在系统运行过程中内容频繁改变的可变(variable)文件。还有分配给每个用户的/home目录,它为各用户存放其私有文件。 (2)Linux导航工具 下面介绍5个最为基础和必备的Linux导航命令(ls、pwd、cd、cat和less)。 1)ls(LIST,列举) 在当前目录下,可以用ls列出文件及子目录的名字。带有l标志(l表示long,即长格式)的ls命令不仅会列出对象的名字,还会列出文件的权限、所有者、组文件大小以及时间戳等信息。为命令添加诸如/var/的目录名称则会显示该目录下的内容,如下所示: ![]() 当给ls-l命令添加h参数时,会以用户可读的格式——KB(千字节)、MB(兆字节)以及GB(千兆字节)来显示文件的大小,而不是字节形式,后者包含很多难以计数的数位: ![]() 通常可以用以下两种方式之一为Linux命令添加参数:一个破折号后跟一个字母(就像修饰ls命令的参数h),或者两个破折号来引用该参数更为冗长的形式。本例中,ls--human-readable会得出与ls-h完全相同的输出。 想知道在当前目录下有什么内容吗?为ls命令添加一个大写的R参数会显示子目录及它们包含的文件与子目录,无论这些目录的嵌套层数有多少。为了恰当地呈现结果会是多么有关以及多么有用,只需对/etc/目录树再次运行ls-h命令: $ ls -R /etc 2)pwd(显示工作目录) 很多情况下,在文件系统中所处的当前位置会显示在命令提示符的左侧。本例中,当前用户位于/etc/目录下的network目录中: ubuntu@base:/etc/network$ 由于可能发现自己工作的系统上没有提示符,而有时又可能需要快速地了解当前的位置。此时,输入pwd命令将打印出用户当前所处的工作目录: $ pwd /etc/network 3)cd(改变目录) 一旦知道了当前所处的位置以及在当前目录下能够立即访问的内容,将需要知道如何改变位置。在命令行解释器(通常为Bash)中输入cd命令可以切换到指定目录。当用户第一次打开一个终端会话(常被称为shell)时,用户将发现其已默认地进入自己账户的home目录。如果运行pwd命令,将可能看到类似下面的信息: $ pwd /home/用户名 何为Bash?Bash可能是最流行的UNIXshell。非常好!但shell是什么?shell是唯一通过命令行接口(CLI)或图形用户接口(GUI)解释用户命令的用户接口。可以将shell(如下图中所示)看作是使用下层内核与硬件系统资源来执行所有适当格式化命令的软件层。换句话说,它是用户与计算机交流的方式。 ![]() shell解释用户输入命令的执行 现在,让我们通过输入命令cd和正斜杠返回根目录: cd / 再次运行ls命令,看看会显示什么(将看到图2中呈现的目录)。可以从home目录访问yourname目录。要想切换到这里列出的子目录中的任何一个,请输入cd及想要访问的目录名。由于这里给定的路径是当前位置的相对(relative)位置,就无须在该目录名前增加一个正斜杠字符。cd..命令将会回退上一级目录,例如,从/home/yourname/目录回退到/home/。 如果想查看远离当前目录的内容,将需要使用绝对(absolute)路径。这意味着将一直使用一个以根目录(用正斜杠表示)开始的路径。要想从系统的其他某处返回用户的home目录,请依次输入正斜杠、home(请记住,其在根目录中)及用户名。可以尝试如下命令: $ cd /home/yourname 也就是说,输入不带参数的cd命令将回到当前登录用户的home目录。 4)cat(将文件内容打印到输出) 在一个终端中访问文本文件的内容有时可能会有些棘手。cat工具会把文件内容打印到屏幕,允许阅读但不能编辑。对于诸如/etc/目录下的fstab等较短的文档而言,这种方式会运行得非常好。下面的示例中使用了一个绝对路径,从而,无论当时处于文件系统中的什么位置,该文件都能被找到: $ cat /etc/fstab 命令名cat实际上是concatenate的缩写,它反映出该工具的用途是将多个字符串或文件连接到单个文本流中。 假设想要读取的文件所包含的行数超过了单屏可以显示的行数。例如尝试查看/etc/group文件: cat /etc/group 可能的情形是,前面的行向屏幕上方滚动和消失的速度太快,以致无法阅读。如果不能阅读纯文本文件,那它能有什么用处呢?当然,如即将看到的,Linux提供了大量的文本编辑器来管理内容,但是,能够每次一屏地阅读一个长文件会是非常好的。 5)less(显示文件内容) 欢迎使用less命令——推测一下,这样命名应该是由于它能快速地读取和显示少于(less)整个文件的内容(或者,可能是为了将其与早期的more命令进行对应区分)。通过对一个现有文件运行less命令即可启动该命令: less /etc/services 使用less命令,你可以使用箭头、PgUp(上翻页)、PgDn(下翻页)以及空格键来上翻、下翻整个文件。工作完成后,按下q键退出。 (3)Linux文件管理工具 如果您已经获得了文件和目录,将需要了解如何创建、删除、移动和复制它们。文件通常是由软件安装或自动的日志生成等外部过程自动创建的,或者说,是将您的工作保存在像LibreOffice这样的办公工具包中时创建的。可以使用touch命令来快速地创建一个空文件,命令后面是想起的文件名: $ touch myfile 然后使用ls命令就可以看到,该文件已经存在于当前目录中。使用cat命令来显示文件的内容,当然,因为之前只是创建了文件,因此该命令执行后根本不会显示任何内容: $ ls myfile $ cat myfile 使用touch命令来“触及”一个已存在的文件会更新该文件的时间戳,而不会对其内容做任何更改。如果因为某种原因想更改如ls等不同命令列举或显示文件的顺序,那么这就很有用。 这里有三类编辑器适合您的工作: ● 如果您更喜欢处理GUI环境中的文档,那么一个简单的纯文本编辑器(plain-text editor,Ubuntu中称为Text Editor),如gedit,就非常好了。不同的语法高亮工具也可以让编码和脚本编写更为高效,而且可以非常确信这类工具只会保存您所见的文本内容。 ● 当需要从终端会话中编辑一个文件时,具有直观接口的nano(或Pico)等命令行编辑器(command-line editor)就可以胜任。 ● 最后是Vim(或者其原始版本:vi)。如果您愿意用几个月的时间来学习一个令人费解的接口主要是什么,那么,您将获得大大提高工作效率的终生回报。就这么简单。 用上述的三个文本编辑器对所创建的myfile文件做一些编辑呢,示例如下: $ nano myfile $ vi myfile 对于Vim编辑器,用i键可以进入插入模式(Insert Mode),然后输入文本。如果不想将余生都陷入Vim中,可以先按下Esc键,再输入:w,即可保存所做的编辑工作,之后输入:q退出。 创建和删除目录 Linux文件系统中的每一个对象都是由称为i结点(inode)的元数据的唯一集合来表示的。文件系统索引是从驱动器上与所有这些i结点相关的元数据得来的。要想显示之前用touch命令创建的文件的更多信息,包括i结点信息,可以使用stat命令,操作及结果如下: ![]() 输出数据包括文件名、文件属性和时间戳。但是,它也给出了i结点的ID号。重要的是要意识到,当移动、复制或删除一个文件或目录时,真正进行的操作是编辑它的i结点属性,而非它的ID。顺便说一下,i结点是UNIX系统采用的对象,用以确定物理存储位置及其在文件系统中的文件属性(如图2所示)。通常,每个文件或目录将只对应一个i结点。 假设您正位于自己的home目录,为什么不创建一个用于实验的新目录呢?为此,需要使用mkdir命令: $ mkdir myplace 现在,转到新的目录并在该目录下创建一个文件: $ cd myplace$ touch newfile $ ls newfile 接下来,可以看到如何删除对象,回退到父目录(使用cd..)并删除刚刚建立的目录。奇怪的是,预先定义的目录删除命令rmdir在这种情况下并不工作。请试试: $ cd .. $ rmdir myplace rmdir: failed to remove 'myplace' : Directory not empty “目录不能为空?”什么意思?这是一个内置的检查,以防止意外删除可能已经忘记仍存放有重要文件或子目录的目录。要解决这个问题,可以做一些处理。 一种方法是为rmdir命令增加--ignore-fail-on-non-empty参数,但是该参数需要令人厌烦的大量输入。另一种方法是手动访问每个子目录,并逐个删除所能发现的每个对象。但某些时候这可能会相当糟糕。当百分之百确定目录下绝对没有所需要的内容时,最快的方法是为rm命令添加-r标志(表示递归,recursive): $ rm -r myplace 基于GUI桌面接口和使用命令行进行工作的一个重要区别:命令行没有回收站。如果用rm(或rmdir)删除了某些内容,之后又后悔了,总的来说,是没有办法进行恢复的。毕竟,考虑一下即将释放的存储空间。 拷贝并移动文件 接下来,创建一些文件及一个新目录: $ touch file1 file2 file3 $ mkdir newdir 使用cp命令可以创建一个与对象完全相同的副本。这个示例中,在newdir目录中创建file1文件的一个副本: $ cp file1 newdir cp命令知道该命令行应该做什么,因为它足够聪明,可以识别newdir是一个文件夹而不是一个文件。如果当前位置中没有名为newdir的目录,cp命令反而会创建一个新的名为newdir的file1文件副本。有时可能会意外地拼错命令,那么最终会得到一个奇怪的新文件而不是希望的目录。无论如何,要检查并确认每件事都在按照预期进行工作。 与cp命令不同,mv命令会永久地把文件从一个位置移动到另一个位置。因此,如果要把一个文件从home目录移动到newdir子目录,原始文件将不复存在: $ mv file2 newdir 请再一次亲自检查结果。可以使用与文件操作相同的命令来复制、移动或删除目录,在有必要的地方也可以添加-r标志。请记住,正在移动的可能不仅仅是看到的目录:任何已存在的不可见的嵌套层也会被移动。 文件名通配符 如果要移动或复制多个文件,并且想要避免逐个输入所有的文件名,通常可以使用通配符(*)来进行全局操作。为了将当前目录下的所有内容移动到某个其他位置,可以进行如下操作: $ mv * /some/other/directory/ 仅要移动文件名中包含特定字符串的文件时,可以尝试如下命令: $ mv file* /some/other/directory/ 该命令会移动文件名以file开始的文件,同时不会影响其他文件。如果文件名有file1、file2……file15且只想移动从file1到file9的文件,应该使用问号(?)而不是星号(*): $ mv file? /some/other/directory/ 这个问号表示,仅对文件名中包含file及一个其他字符的文件进行操作。这会将文件file10到file15保留在当前目录中。 删除文件 可以用rm删除对象。但请记住,这些操作实际上是不可逆的。如果想删除文件file1,可以输入如下命令: $ rm file1 文件名通配符也可以采用与cp或mv相同的方式在rm命令中使用,而且效果相同。因此,如下命令将会删除当前目录下以file开头的所有文件: $ rm file* 为删除操作添加-r参数将执行递归删除,并且删除指定路径下所有子目录中的内容: $ rm -r * 实际上,这种组合是非常危险的,以root权限工作时更是如此,因为此时也可以操作所有的系统文件。所以,在广泛使用rm命令之前,的确应该非常谨慎。 (4)键盘技巧 剪切与粘贴 尽管已经看到了相反的情况,但可以向终端中复制或粘贴文本。的确,大家所熟悉的组合键Ctrl-c(复制)和Ctrl-v(粘贴)在Bash shell会话中并不能使用,但是Shift-Ctrl-c和Shift-Ctrl-v则是可以的。也可以点击鼠标右键并选择菜单中的操作来进行剪贴和粘贴。这将很不相同。只要想象一下,从可靠的在线资源中偶然得到了一个确实很长的命令序列,就像下面的命令序列: ![]() 在这里,剪切和粘贴非常有用。 TAB键补齐 Bash会跟踪您的位置及环境,并在您输入新的命令时进行监视。基于当前环境中的文件和目录,如果您输入的字符包含任何关于您的最终目标的线索,按下Tab键让Bash在命令行上显示出最佳的推荐结果。如果这就是您要的结果,按下回车键并开始执行就好了。 这里给出一个示例。假设已经下载了一个全名为foo-matic-plus_0.9.1-3_amd64.deb的软件归档文件。想将该文件复制到可以将其解压的工作目录中。通常情况下,需要输入如下命令: $ sudo cp foo-matic-plus_0.9.1-3_amd64.deb /usr/bin/foo-matic/ 但是,如果该文件就在当前目录下且假设它是目录中以foo开始的唯一文件,那么要做的只是敲入cp foo并按下Tab键。Bash会补齐文件名的剩余部分。当然,由于Bash没有读心术,至少还得敲入足够的目的位置信息以便用Tab键补齐剩余内容。 自己尝试一下。使用touch创建一个文件名奇长的文件,然后尝试用Tab键补齐的方法来删除或复制该文件。以下给出例子: $ touch my-very-silly-filename_66-b.txt $ rm my-<tab> (5)伪文件系统 一个标准文件是可以被重复访问的数据的集合。相反,Linux伪文件(就像那些存在于/sys/和/proc/目录中的文件)中的内容并不以通常形式存在。伪文件中的内容由操作系统动态生成,用于表示某些特定的值。 例如,可能想知道某个硬盘的总空间有多少。让我们使用名为cat的命令行程序来读取系统的一个文件,该文件包含sda硬盘上的字节数量: ![]() 如果系统中的第一个存储设备被称为/dev/sda,那么,第二个就是/dev/sdb,第三个会是/dev/sdc。最初,sda可能表示SCSI Device A(SCSI设备A),但发现将其理解为Storage Device A(存储设备A)更有意义。也许还会遇到设备名如/dev/hda(硬盘驱动器)、/dev/sr0(DVD驱动器)、/dev/cdrom(是的,一个CD-ROM驱动器),或者,甚至是/dev/fd0(软盘驱动器)。 还有相当简单的方法来获取该类信息。例如,在图形用户界面文件管理器中,在驱动器上可以点击鼠标右键,但是,/sys/目录中的伪文件是所有系统进程所依赖的公共资源。 不知道驱动器名称吗?没关系。我们知道Linux以块设备(block device)的模式来组织连接的存储器,切换到/sys/block/目录并列出其内容即可。在这些内容中有一个名为sda/的目录(请记住sda代表存储设备A)。这是系统启动时使用的第一个驱动器: ![]() 请移动至sda/目录并运行ls命令。在目录中,可能会看到名如sda1、sda2及sda5的一些文件。每一个文件都表示Linux创建的一个分区,这可以更好地组织驱动器上的数据: ![]() (6)sudo 出于实际考虑,使用具有全部管理权限的操作系统账户来日复一日地进行计算是没有必要且是非常危险的。另一方面,将完全限制您为没有管理权限,也极有可能会让您无法完成任何工作。 许多Linux版本都通过提供具有管理员权限的选定账户来解决这一问题,该授权在大多数场合下只是纯理论的,但在需要时可以通过在命令前加上sudo来进行调用。一旦用密码验证了身份,命令就会被当作root用户的命令来处理: ![]() 在安装Linux时默认创建的用户将具有sudo权限。 说明命令行示例时,对于不需要管理员权限的命令使用命令提示符$表示,对于需要管理员权限的命令则使用#表示,而非$sudo。由此,一个非管理员的命令具有如下形式: $ ls 一个sudo命令则具有如下形式: # nano /etc/gruop 3、获取帮助 无论如何,IT项目常常会带来麻烦。解决首次遇到的问题,或是面对一个很久都没有遇到的任务以致您忘记了精确的语法,这些情况都可能会很复杂。您将需要寻求帮助。以下是一些值得关注的内容。 (1)man文件 依照惯例,创建和维护支持Linux命令的软件开发人员也会编写一个高度结构化的文档手册,称为man文件。当安装了一个Linux程序,其man文件通常会被随之安装,进而可以在命令行输入man及命令名来查看这些帮助文件。man系统本身也有一个man文件,所以,我们可以如下形式来访问: $ man man 当您在自己的计算机上运行该命令时,将看到第一个字段NAME,它包括命令的简介,SYNOPSIS提供了详细的语法信息,DESCRIPTION提供了该程序的更多描述,它通常包括一个命令行及参数列表。如果幸运的话,EXAMPLES中会有一些有用的示例。 有时,man文件可能会非常大,因此,浏览整个文档来查找一个特定的细节是不切实际的。鉴于各种历史原因,在浏览器及文字处理工具等现代应用中可用的本地搜索操作组合键Ctrl-f在这里并不可用。为顶替它,按下/键可以切换至屏幕底部的文字输入区,在这里可以输入要搜索的内容。如果第一个高亮显示的内容并非要查找的,按下n键(如果需要的话,按很多次)对文档进行前向搜索以查找相同的串,直至找到所需的内容。 (2)info命令 如果碰巧知道所要查询的命令或程序的名字,man系统就非常适用。但假设忘了命令的名称。在命令提示符后输入info,根据Bash标准将被带入一个完全交互式的环境中: $ info 如图3所示,其内容按照主题首词(如Basics和Compression)字母顺序组织。可以用上、下箭头按键来滚动行;当找到了感兴趣的主题,即可按下回车键切换到该主题的页面。 ![]() 图3 Info主菜单的第一屏。Info链接在你的系统上看起来可能会有所不同,这取决于安装的软件 假如您想学习更多关于文件权限的内容。从Basics区域向下滚动,直到到达File permission(文件权限),按下回车键。该页的Menu section(菜单区域)说明其后的行是切换到更多下一级页面的链接。按下u键返回到上一级页面,按下q键将完全退出Info工具。 默认情况下Info系统可能不会安装在一些Linux服务器的发行版中。如果在命令提示符后输入info不能给您想要的结果,可以使用命令sudo apt install info来进行安装(在Ubuntu/Debian系统中)。 (3)互联网 无论认为自己有多么无助,拥有不同经验的成千上万的Linux管理员已经遇到了相同类型的问题并已经解决了。很多解决方案正是从链接serverfault.com或linuxquestions.org/questions等在线社区论坛中搜索得来的。 互联网搜索引擎可以很好地将已经被问过和回答过的问题罗列出来。一个形式良好的搜索查询常常能比从头开始整个过程更快地获得所需的内容。 关键在于要知道如何进行智能搜索。在搜索栏中输入my server crashed(我的服务器崩溃了)并希望得到最佳答案可能没什么用。显然,这需要更多的细节。服务器的类型是什么,Apache Web服务器?浏览器中是否出现了某些错误信息?服务器崩溃时是否生成了任何的日志条目?找出这些信息会是一个好想法。 从系统日志中获取错误信息 在几乎所有的现代Linux发行版中(Ubuntu 14.04除外),可以用journalctl命令来访问所有的系统日志: # journalctl 无参数运行journalctl将让您陷入大量的数据流中。要用某种方法将需要的信息过滤出来。grep命令如下: ![]() 在该示例中,使用了竖杠(|),在美式键盘布局中可以用Shift-\按键组合将其输入。它将journalctl命令的输出输送给grep过滤器,过滤器仅会将包含filename.php字符串的那些行输出到屏幕上。当然,假设您的Web服务器正在运行PHP内容,而且,有一个文件的名字是filename.php。通常可以采用更具描述性和更有用的名字,如stuff.php。 可以进一步通过使用多个grep组成的命令序列来限定要搜索的结果。假设通过filename.php可以找到多个日志条目,而且仅需要包含error一词的那些条目。可以将第一个操作的结果以管道输送到第二个grep命令,用error过滤: # journalctl | grep filename.php | grep error 如果只想获取那些不包含error一词的条目,可以添加-v(查找相反的结果)参数: # journalctl | grep filename.php | grep -v error 在互联网上搜索 现在,想象一下从journalctl得到的输出包含如下内容: ![]() 这可能是有用的。在互联网上搜索时间戳或特定的IP地址毫无意义,但可能有人已经遇到过Client sent malformed Host header(客户端发送了格式错误的主机头)。 要减少误报,可能会希望将单词括在引号中,以便搜索引擎仅返回与该完整短语匹配的结果。最小化误报的另一种方法是告诉搜索引擎忽略包含特定字符串的页面。 微信公众号:计算机与网络安全 ID:Computer-network 【推荐书籍】 ---------------------------------------------------------------------------------------------------------------------- 我们尊重原创,也注重分享,文章来源于微信公众号:计算机与网络安全,建议关注公众号查看原文。如若侵权请联系qter@qter.org。 ---------------------------------------------------------------------------------------------------------------------- |