第1章.初识Linux shell

Linux可划分为以下四部分:

  1. Linux内核
  2. GNU工具
  3. 图形化桌面环境
  4. 应用软件

1554343685930

内核主要负责以下四种功能:

  1. 系统内存管理
  2. 软件程序管理
  3. 硬件设备管理
  4. 文件系统管理

内存存储单元按组划分成很多块,这些块称作页面(page).
内核将每个内存页面放在物理内存或交换空间。然后,内核会维护一个内存页面表,指明哪些页面位于物理内存内,哪些页面被换到了磁盘上。

内核创建了第一个进程(称为init进程)来启动系统上所有其他进程。
内核在启动任何其他进程时,都会在虚拟内存中给新进程分配一块专有区域来存储该进程用到的数据和代码。

Linux系统将硬件设备当成特殊的文件,称为设备文件。设备文件有3种分类:

  1. 字符型设备文件
  2. 块设备文件
  3. 网络设备文件

字符型设备文件是指处理数据时每次只能处理一个字符的设备.
块设备文件是指处理数据时每次能处理大块数据的设备,比如硬盘。
网络设备文件是指采用数据包发送和接收数据的设备,包括各种网卡和一个特殊的回环设
备。这个回环设备允许Linux系统使用常见的网络编程协议同自身通信。

Linux为系统上的每个设备都创建一种称为节点的特殊文件。与设备的所有通信都通过设备节点完成。每个节点都有唯一的数值对供Linux内核标识它(类似于python中的id)。
数值对包括一个主设备号和一个次设备号。类似的设备被划分到同样的主设备号下。次设备号用于标识主设备组下的某个特定设备。

供Linux系统使用的这组核心工具被称为coreutils(coreutilities)软件包。
GNU coreutils软件包由三部分构成:

  1. 用以处理文件的工具
  2. 用以操作文本的工具
  3. 用以管理进程的工具

shell是一种特殊的交互式工具。它为用户提供了启动程序、管理文件系统中的文件以及运行在Linux系统上的进程的途径。

shell在命令行中执行,你也可以将多个shell命令放入文件中作为程序执行。这些文件被称作shell脚本

Linux的shell其实有好多种,最常用的就是bash shell.

我们将完整的Linux系统包称为发行版。

发行版 描述
CentOS 一款基于Red Hat企业版Linux源代码构建的免费发行版
Ubuntu 一款用于学校和家庭的免费发行版
PCLinuxOS 一款用于家庭和办公的免费发行版
Mint 一款用于家庭娱乐的免费发行版
dyne:bolic 一款用于音频和MIDI应用的免费发行版
Puppy Linux 一款适用于老旧PC的小型免费发行版

第2章.走进shell

shell中的快捷键一般是 Ctrl + Shift +:

Ctrl + Shift + T : 打开shell
Ctrl + Shift + N : 新建一个shell
Ctrl + Shift + F : 搜索
Ctrl + Shift + H : 向后搜索
Ctrl + Shift + G : 向前搜索

在Linux的shell中,复制粘贴是Ctrl + Shift +C/V

第3章.基本的bash shell命令

概述

默认bash shell提示符是美元符号($),

1
2
3
4
# Ubuntu系统的提示符:用户名为achilles,系统名ubuntu
achilles@ubuntu:~$
# CentOS系统的提示符:用户名为christine,系统名server01
[christine@server01 ~]$

当使用man命令查看命令手册页的时候,这些手册页是由分页程序(pager)来显示的。分页 程序是一种实用工具,能够逐页显示文本。可以通过点击空格键进行翻页,或是使用回车键逐行查看。另外还可以使用箭头键向前向后滚动手册页的内容。

手册页将与命令相关的信息分成了不同的节。
如果不记得命令名怎么办?可以使用关键字搜索手册页。语法是:man -k 关键字。例如,要查找与终端相关的命令,可以输入man -k terminal。

除了man,info命令用于查看帮助,很多命令都支持–help来查看帮助.

不像Windows,Linux在路径名中不使用驱动器盘符。(eg:c:\Users\Rich\Documents\test.doc )
Linux将文件存储在单个目录结构中,这个目录被称为虚拟目录(virtual directory)。
Linux虚拟目录结构只包含一个称为根(root)目录的基础目录。根目录下的目录和文件会按 照访问它们的目录路径一一列出,这点跟Windows类似。 (eg:/home/Rich/Documents/test.doc)

通常系统文件会存储在根驱动器中,而用户文件则存储在另一驱动器中
1554433336449
上面展示了计算机中的两块硬盘。一块硬盘和虚拟目录的根目录(由正斜线/表示)关联起 来。剩下的硬盘就可以挂载到虚拟目录结构中的任何地方。
在这个例子中,第二块硬盘被挂载到了/home位置,用户目录都位于这个位置。

目 录 用 途
/ 虚拟目录的根目录。通常不会在这里存储文件
/bin 二进制目录,存放许多用户级的GNU工具
/boot 启动目录,存放启动文件
/dev 设备目录,Linux在这里创建设备节点
/etc 系统配置文件目录
/home 主目录,Linux在这里创建用户目录
/lib 库目录,存放系统和应用程序的库文件
/media 媒体目录,可移动媒体设备的常用挂载点
/mnt 挂载目录,另一个可移动媒体设备的常用挂载点
/opt 可选目录,常用于存放第三方软件包和数据文件
/proc 进程目录,存放现有硬件及当前进程的相关信息
/root root用户的主目录
/sbin 系统二进制目录,存放许多GNU管理员级工具
/run 运行目录,存放系统运作时的运行时数据
/srv 服务目录,存放本地服务的相关文件
/sys 系统目录,存放系统硬件信息的相关文件
/tmp 临时目录,可以在该目录中创建和删除临时工作文件
/usr 用户二进制目录,大量用户级的GNU工具和数据文件都存储在这里
/var 可变目录,用以存放经常变化的文件,比如日志文件

在登录系统并获得一个shell CLI提示符后,会话将从主目录开始。
主目录是分配给用户账户的一个特有目录。用户账户在创建之后,系统通常会为其分配一个特有的目录。

cd

cd destination:destination可以使用绝对路径或者相对路径.

1
2
3
4
# $前面有一个~
achilles@ubuntu:~$ cd /usr/bin
# cd结束后~被/usr/bin替代了。
achilles@ubuntu:/usr/bin$

原因:
CLI提示符正是用它来帮助你跟踪当前所在虚拟目录结构中的位置
==波浪号表明shell会话位于你的主目录中(注意不是根目录)==。在切换出主目录之后,如果提示符已经进行了相关配置的话,绝对文件路径就会显示在提示符中

1
2
3
# 所以cd ~就是cd到主目录中
# 跳转到/home/liangbo
cd ~

主目录和根目录:
主目录就是当前用户的目录(eg:/home/liangbo),根目录就是真正的/
他们的层级关系看上面的”Linux文件结构”图

和python一样,有两个特殊字符可用于相对文件路径中:

  • 单点符(.),表示当前目录;
  • 双点符(..),表示当前目录的父目录。

ls

注意,ls命令输出的列表是按字母排序的.
使用**-F参数的ls命令可以区分文件和目录**。(文件夹带有/,可执行文件带有星号)

1554435845497

ls命令并没有将全部文件和文件夹都显示出来(Linux经常采用隐藏文件来保存配置信息。)
在Linux上,隐藏文件通常是文件名以点号开始的文件。使用**-a属性显示隐藏文件**.

1554435151535

注意,有三个以.bash开始的文件。它们是bash shell环境所使用的隐藏文件

-R参数是ls命令的另一个参数,叫作递归选项。**-R列出当前目录下包含的子目录中的文件**。
eg:dir5中有dir6,dir6中有dir7

1554435771757

-l参数会产生长列表格式的输出,包含了目录中每个文件的更多相关信息。

1554436148675

上面的信息包括:

  1. 文件类型,比如目录(d)、文件(-)、字符型文件(c)或块设备(b);
  2. 文件的权限;
  3. 文件的硬链接总数;
  4. 文件属主的用户名;
  5. 文件属组的组名;
  6. 文件的大小(以字节为单位);
  7. 文件的上次修改时间;
  8. 文件名或目录名。

ls命令最长使用的参数 -lrt(-l:以列表形式显示,-r:逆序,-t:以时间排序)

1554436548017

ls还携带过滤器,在后面添加要查找的文件名即可:
注意文件名必须是全名且名字正确,否则可以使用通配符:

  • 问号(?)代表一个字符;
  • 星号(*)代表零个或多个字符

1554437036303

星号和问号被称为文件扩展匹配,这和word中的通配符是同样的功能.
通配符正式的名称叫作元字符通配符

需要注意的是,==对于文件夹”dir”,使用ls d?r是拿不到的==,需要使用ls d?r*

通配符还可以和正则表达式类比.

1
2
3
4
5
6
# a或i
$ls -l my_scr[ai]pt
# a到i
$ ls -l f[a-i]ll
# 不包括a
$ ls -l f[!a]ll

touch

touch命令不仅可以创建指定的新文件,文件的大小是零.
touch命令还可用来改变文件的修改时间。这个操作并不需要改变文件的内容。

1554558085463

有修改时间,就有访问时间,如果touch要改变访问时间,就需要使用-a参数.
(注意:如果只使用ls –l命令,并不会显示访问时间。这是因为默认显示的是修改时间。
要想查看文件的访问时间,需要加入另外一个参数:–time=atime)

而且–time=atime必须配合-l命令.因为ls命令本来就不能显示时间.

1554558791048

cp

cp命令需要两个参数——源对象和目标对象:cp source destination
cp命令将源文件复制成一个新文件,并且以 destination命名。新文件就像全新的文件一样,有新的修改时间.

注意cp命令是覆盖型的,也就是说,

1
cp test_one test_two

如果test_two本身就存在,那么他就会被覆盖掉.
这时就需要使用-i参数:(后面输入y/n)
1554559126935

需要注意的是,cp可以将文件复制到其他地方:

1
2
3
4
# 将文件test_one移动到同级目录dir1下面
cp test_one dir1/
# 注意必须使用dir1/,而不是dir,dir1/直接说明了这是一个目录
# 假设dir1不存在,使用cp test_one dir1/就会弹出错误,但是使用cp test_one dir1就会创建一个dir文件,根本不会弹出错误.导致你错了都不知道.

上面代码是将当前文件复制到其他文件夹中,如果需要将其他目录下的文件复制到当前目录下.就可以==使用点号==

1
2
3
4
# 将dir1目录下的test_one文件复制到当前目录中
cp dir1/test_one .
# 将dir1目录下所有以test开头的文件复制到当前目录中
cp dir1/test* .

-l参数:复制文件的硬链接文件

-R参数递归地复制整个目录的内容。

文件链接(ln)

在Linux中有两种 不同类型的文件链接:

  1. 符号链接
  2. 硬链接

符号链接就是一个实实在在的文件,它指向另一个文件。 这两个通过符号链接在一起的文件,彼此的内容并不相同。 可以==使用ln命令以及-s选项来创建符号链接==。

1
2
# 创建一个符号链接file2,使file2指向file1
ln -s file1 file2

1554561728385

1554561857254

证明链接文件是独立文件的方法是查看inode编号。文件或目录的inode编号是一个用于标识的唯一数字,这个数字由内核分配给文件系统中的每一个对象。(类似于python里的id)
要查看文件或目录的inode 编号,可以给ls命令加入-i参数(刚好就是id的i)

1
2
3
ls -i file*
# 得到:402949 file1 402947 file2
# 一个编号是402949,一个编号是402947:说明是不同的文件

如何理解硬链接:
就像是python的内存数据和变量引用之间的关系,只要引用不为0,那么内存数据就会一直存在.
类比于硬链接,硬链接就是对内存数据的引用,我们使用cp -l file1 file2其实就是新建一个引用file2,这个file2指向file1这个内存.所以就算以后file1被删除了,那么指向内存数据的引用就会少了一个,还是有file2引用到内存数据,一样可以使用内存数据.

简单来说:
==硬连接记录的是目标的 inode,符号连接记录的是目标的 path==。
==软连接就像是快捷方式,而硬连接就像是备份!==
符号连接可以做跨分区的 link;而硬连接由于inode的缘故,只能在本分区中做 link.所以,符号连接的使用频率要高的多。

ln默认创建的是硬链接。使用 -s 开关可以创建符号链接

复制链接文件的时候一定要小心。如果使用cp命令复制一个文件,而该文件又已经被链接到了另一个源文件上,那么你得到的其实是源文件的一个副本
==千万别创建软链接文件的软链接==。这会形成混乱的链接链,不仅容易断裂,还会造成各种麻烦。

重命名文件(mv)

在Linux中,重命名文件称为移动(moving)。因为mv命令既可以移动也可以重命名.
简单来说,mv既可以移动也可以重命名,这取决与第二个参数是文件名还是目录名

1
2
3
4
5
6
# 将file2移动到dir2
mv file2 dir2/
# 将file2重命名为file3
mv file2 file3
# 将file2移动到dir2同时重命名为file3
mv file2 dir2/file3

mv不管是重命名还是移动,inode编号时间戳保持不变.

==mv也有覆盖的问题,需要使用-i来询问==(注意:没有发生问题的时候是不会提醒的)

删除文件(rm)

-i命令参数提示你是不是要真的删除该文件。

如果删除整组的文件,-i会一个个的问过去:

1554595359904

和-i相反,使用-f就是不询问是否删除,然后直接强制删除.

处理目录(mkdir,rmdir,file,cat,less.more,tail,head)

1
2
3
4
# 创建目录
mkdir new_dir
# 使用-p创建多级目录
mkdir -p new_dir/new_dir2/new_dir3

一般我们删除目录使用的是rm -rf dir1,但是还有一个rmdir命令.

rm在没有-r参数的时候只能删除空目录,rmdir同理.(-r是递归的意思,所以rm -r就是递归删除)
所以说,-r选项使得命令可以向下进入目录,删除其中的文件,然后再删除目录本身。

rmdir没有-r参数,所以rmdir只能删除空目录.

查看文件内容

file:查看文件类型

1
2
3
4
5
6
7
# 查看dir2的文件类型,返回dir2: directory
file dir2/
# 查看new_file的文件类型,返回dir2/newfile: empty
file dir2/newfile
# 甚至能看符号链接文件所指的源文件所在地
# 查看file2的文件类型,返回file2: symbolic link to file1
file file2

查看整个文件

cat:显示文本文件
-n参数会给所有的行加上行号。 -n会给空行也加上行号,
-b参数会只给有文本的行加上行号.
-T参数不显示制表符(制表符会变成^I)

cat会一次性加载全部的文件内容.
more命令能按页加载文件内容

1554597434399

需要使用:空格进行下一页,回车进行下一行,q进行取消

less就是more命令的升级版,它提供了一些极为实用的特性,能够实现在文本文件中前后翻动,而且还有一些高级搜索功能。

查看部分文件

more命令确实能按页呈现.
但是如果我看需要查看的内容在中间怎么办.这时需要使用head和tail命令

tail命令会显示文件后几行的内容(文件的“尾部”)。
默认情况下,它会显示文件的末尾10行。

tail使用-n参数修改显示几行

1
2
3
4
# 显示file2的最后3行
tail -n 3 file2
# 简写成:
tail -3 file2

-f参数是tail命令的一个突出特性。
它允许你在其他进程使用该文件时查看文件的内容。 tail命令会保持活动状态,并不断显示添加到文件中的内容。这是实时监测系统日志的绝妙方式。
简单来说,==-f参数能让tail命令保持活动状态,实时监控文件==.

head命令,顾名思义,会显示文件开头那些行的内容。默认情况下,它会显示文件前10行的文本.head命令和tail命令差不多,都是使用-n参数的:

1
2
# 显示file2的头三行
head -3 file2

小结

  1. cd命令在虚拟目录里切换目录。
  2. ls命令列出目录中的文件和子目录。
  3. touch命令创建空文件和变更已有文件的访问时间或修改时间。
  4. cp命令将已有文件复制到其他位置。
  5. ln命令复制硬链接和符号链接。
  6. mv和rm命令移动文件移除文件。
  7. mkdir和rmdir命令移动文件移除文件目录。
  8. cat、more和less命令查看文件全部内容。
  9. tail和head命令查看文件中的一小部分内容。

第4章.更多的bash shell命令

本章将详细介绍Linux系统管理命令

监测程序

探查进程(ps,top)

ps命令能输出运行在系统上的所有程序的许多信息。 ps命令参数及其复杂,
默认情况下,ps命令只会显示运行在当前控制台下的属于当前用户的进程。

1554599225461

上例中的基本输出显示了程序的进程ID(Process ID,PID)、它们运行在哪个终端(TTY) 以及进程已用的CPU时间。

Linux系统中使用的GNU ps命令支持3种不同类型的命令行参数:

  • Unix风格的参数,前面加单破折线
  • BSD风格的参数,前面不加破折线
  • GNU风格的长参数,前面加双破折线。

查看系统上运行的所有进程:-ef
(-e参数指定显示所有运行在系统上的进程;-f参数则扩展了输出,这些扩展的列包含了有用的信息)

1554599567084

  • UID:启动这些进程的用户。
  • PID:进程的进程ID。
  • PPID:父进程的进程号(如果该进程是由另一个进程启动的)。
  • C:进程生命周期中的CPU利用率。
  • STIME:进程启动时的系统时间。
  • TTY:进程启动时的终端设备。
  • TIME:运行进程需要的累计CPU时间。
  • CMD:启动的程序名称

ps命令的不足之处:它只能显示某个特定时间点的信息。
top命令跟ps命令相似,能够显示进程信息,但它是实时显示的。

1554599934835

上图的表是实时变动的.也就是说,==top命令是实时监控进程的==

第一行load average有三个值:近1分钟的、近5分钟的和近15分钟的平均负载。

第二行显示了进程概要信息——top命令的输出中将进程叫作任务(task):有多少进程处在 运行、休眠、停止或是僵化状态(僵化状态是指进程完成了,但父进程没有响应)。

第三行显示了CPU的概要信息。top根据进程的属主(用户还是系统)和进程的状态(运行、 空闲还是等待)将CPU利用率分成几类输出。

最后两行说明了系统内存的状态。第一行说的是系统的物理内存:总共有多少内存, 当前用了多少,还有多少空闲。
最后一行说的是同样的信息,不过是针对系统交换空间(如果分配了的话)的状态而言的。 后一部分显示了当前运行中的进程的详细列表,有些列跟ps命令的输出类似。

  • PID:进程的ID。
  • USER:进程属主的名字。
  • PR:进程的优先级。
  • NI:进程的谦让度值。
  • VIRT:进程占用的虚拟内存总量。
  • RES:进程占用的物理内存总量。
  • SHR:进程和其他进程共享的内存总量。
  • S:进程的状态(D代表可中断的休眠状态,R代表在运行状态,S代表休眠状态,T代表 跟踪状态或停止状态,Z代表僵化状态)。
  • %CPU:进程使用的CPU时间比例。
  • %MEM:进程使用的内存占可用内存的比例
  • TIME+:自进程启动到目前为止的CPU时间总量。
  • COMMAND:进程所对应的命令行名称,也就是启动的程序名。

结束进程(kill,kiilall)

在Linux中,进程之间通过信号来通信。
进程的信号就是预定义好的一个消息,进程能识别它并决定忽略还是作出反应。

信 号 名 称 描 述
1 HUP 挂起
2 INT 中断
3 QUIT 结束运行
9 KILL 无条件终止
11 SEGV 段错误
15 TERM 尽可能终止
17 STOP 无条件停止运行,但不终止
18 TSTP 停止或暂停,但继续在后台运行
19 CONT 在STOP或TSTP之后恢复执行

kill命令:
kill命令可通过进程ID(PID)给进程发信号。
遗憾的是,你只能用进程的PID而不能用命令名,所以kill命令有时并不好用。

killall命令:
killall命令非常强大,它支持通过进程名而不是PID来结束进程。killall命令也支持通配符,这在系统因负载过大而变得很慢时很有用。

1
2
# 结束所有以http开头的进程
killall http*

监测磁盘空间(mount,umount)

本节将介绍在日常系统管理 中经常用到的核心命令。

如第3章中讨论的,Linux文件系统将所有的磁盘都并入一个虚拟目录下。在使用新的存储媒 体之前,需要把它放到虚拟目录下。这项工作称为挂载(mounting)。

mount命令:
用来挂载媒体的命令。
默认情况下,mount命令会输出当前系统上挂载的设备列表

1554601886705

mount命令提供如下四部分信息:

  • 媒体的设备文件名
  • 媒体挂载到虚拟目录的挂载点
  • 文件系统类型
  • 已挂载媒体的访问状态

要手动在虚拟目录中挂载设备,需要以root用户身份登录,或是以root用户身份运行sudo命 令。下面是手动挂载媒体设备的基本命令:

1
2
# 模板:
mount -t type device directory

type参数指定了磁盘被格式化的文件系统类型。

  • vfat:Windows长文件系统。
  • ntfs:Windows NT、XP、Vista以及Windows 7中广泛使用的高级文件系统。
  • iso9660:标准CD-ROM文件系统

后面两个参数定义了该存储设备的设备文件的位置以及挂载点在虚拟目录中的位置。

1
2
# eg:
mount -t vfat /dev/sdb1 /media/disk

umount命令:
从Linux系统上移除一个可移动设备时,不能直接从系统上移除,而应该先卸载。
卸载设备的命令是umount

1
2
# 模板
umount [directory | device ]

和win一样,如果有任何程序正在使 用设备上的文件,系统就不会允许你卸载它:

df命令:
df命令可以让你很方便地查看所有已挂载磁盘的使用情况

1554602921540