• 信息安全程序设计基础第一周学习总结


     

    一.   Linux系统简介

    1.Linux是一个操作系统

    2.与windows区别

     

    二-基本操作及概念

    三- 用户及权限管理

    四- Linux目录结构及文件基本操作

    五- 环境变量与为文件查找

    六-文件打包与压缩

    七-文件系统操作与磁盘管理

    使用 df 命令查看磁盘的容量

    $ df
    

    在实验楼的环境中你将看到如下的输出内容:

    使用 du 命令查看目录的容量

    这个命令前面其实已经用了很多次了:

    # 默认同样以 blocks 的大小展示
    $ du 
    # 加上`-h`参数,以更易读的方式展示
    $ du -h
    

    -d参数指定查看目录的深度

    # 只查看1级目录的信息
    $ du -h -d 0 ~
    # 查看2级
    $ du -h -d 1 ~
    

     

    1.创建虚拟磁盘

    dd 命令简介(部分说明来自dd (Unix) wiki))

    dd命令用于转换和复制文件,不过它的复制不同于cp。之前提到过关于 Linux 的很重要的一点,一切即文件,在 Linux 上,硬件的设备驱动(如硬盘)和特殊设备文件(如/dev/zero/dev/random)都像普通文件一样,只要在各自的驱动程序中实现了对应的功能,dd 也可以读取自和/或写入到这些文件。这样,dd也可以用在备份硬件的引导扇区、获取一定数量的随机数据或者空数据等任务中。dd程序也可以在复制时处理数据,例如转换字节序、或在 ASCII 与 EBCDIC 编码间互换。

    dd的命令行语句与其他的 Linux 程序不同,因为它的命令行选项格式为选项=值,而不是更标准的--选项 值-选项=值dd默认从标准输入中读取,并写入到标准输出中,但可以用选项if(input file,输入文件)和of(output file,输出文件)改变。

    我们先来试试用dd命令从标准输入读入用户输入到标准输出或者一个文件:

    # 输出到文件
    $ dd of=test bs=10 count=1 # 或者 dd if=/dev/stdin of=test bs=10 count=1
    # 输出到标准输出
    $ dd if=/dev/stdin of=/dev/stdout bs=10 count=1

    使用 mount 命令挂载磁盘到目录树

    用户在 Linux/UNIX 的机器上打开一个文件以前,包含该文件的文件系统必须先进行挂载的动作,此时用户要对该文件系统执行 mount 的指令以进行挂载。通常是使用在 USB 或其他可移除存储设备上,而根目录则需要始终保持挂载的状态。又因为 Linux/UNIX 文件系统可以对应一个文件而不一定要是硬件设备,所以可以挂载一个包含文件系统的文件到目录树。

    Linux/UNIX 命令行的 mount 指令是告诉操作系统,对应的文件系统已经准备好,可以使用了,而该文件系统会对应到一个特定的点(称为挂载点)。挂载好的文件、目录、设备以及特殊文件即可提供用户使用。

    我们先来使用mount来查看下主机已经挂载的文件系统:

    $ sudo mount

    
    

    输出的结果中每一行表示一个设备或虚拟设备,每一行最前面是设备名,然后是 on 后面是挂载点,type 后面表示文件系统类型,再后面是挂载选项(比如可以在挂载时设定以只读方式挂载等等)。

    那么我们如何挂载真正的磁盘到目录树呢,mount命令的一般格式如下:

    mount [options] [source] [directory]
    

    一些常用操作:

    mount [-o [操作选项]] [-t 文件系统类型] [-w|--rw|--ro] [文件系统源] [挂载点]
    

    我们现在直接来挂载我们创建的虚拟磁盘镜像到/mnt目录:

    $ mount -o loop -t ext4 virtual.img /mnt 
    # 也可以省略挂载类型,很多时候 mount 会自动识别
    
    # 以只读方式挂载
    $ mount -o loop --ro virtual.img /mnt
    # 或者mount -o loop,ro virtual.img /mnt

    同样因为环境原因中没有物理磁盘,也无法创建虚拟磁盘的原因我们就无法实验练习使用该命令了,下面我将以我的物理主机为例讲解如何为磁盘分区。

    # 查看硬盘分区表信息
    $ sudo fdisk -l



    八- 命令执行顺序控制与管道
    $ which cowsay>/dev/null && cowsay -f head-in ohch~
    

    你如果没有安装cowsay,你可以先执行一次上述命令,你会发现什么也没发生,你再安装好之后你再执行一次上述命令,你也会发现一些惊喜。

    上面的&&就是用来实现选择性执行的,它表示如果前面的命令执行结果(不是表示终端输出的内容,而是表示命令执行状态的结果)返回0则执行后面的,否则不执行,你可以从$?环境变量获取上一次命令的返回结果:

    学习过 C 语言的用户应该知道在 C 语言里面&&表是逻辑与,而且还有一个||表示逻辑或,同样 Shell 也有一个||,它们的区别就在于,shell中的这两个符号除了也可用于表示逻辑与和或之外,就是可以实现这里的命令执行顺序的简单控制。||在这里就是与&&相反的控制效果,当上一条命令执行结果为≠0($?≠0)时则执行它后面的命令:

    $ which cowsay>/dev/null || echo "cowsay has not been install, please run 'sudo apt-get install cowsay' to install"
    

    除了上述基本的使用之外,我们还可以结合这&&||来实现一些操作,比如:

    $ which cowsay>/dev/null && echo "exist" || echo "not exist"

    1.试用

    先试用一下管道,比如查看/etc目录下有哪些文件和目录,使用ls命令来查看:

    $ ls -al /etc
    

    有太多内容,屏幕不能完全显示,这时候可以使用滚动条或快捷键滚动窗口来查看。不过这时候可以使用管道:

    $ ls -al /etc | less
    

    通过管道将前一个命令(ls)的输出作为下一个命令(less)的输入,然后就可以一行一行地看。

    2.cut 命令,打印每一行的某一字段

    打印/etc/passwd文件中以:为分隔符的第1个字段和第6个字段分别表示用户名和其家目录:

    $ cut /etc/passwd -d ':' -f 1,6

    grep命令是很强大的,也是相当常用的一个命令,它结合正则表达式可以实现很复杂却很高效的匹配和查找,不过在学习正则表达式之前,这里介绍它简单的使用,而关于正则表达式后面将会有单独一小节介绍到时会再继续学习grep命令和其他一些命令。

    grep命令的一般形式为:

    grep [命令选项]... 用于匹配的表达式 [文件]...
    

    还是先体验一下,我们搜索/home/shiyanlou目录下所有包含"shiyanlou"的所有文本文件,并显示出现在文本中的行号:

    $ grep -rnI "shiyanlou" ~

    wc 命令用于统计并输出一个文件中行、单词和字节的数目,比如输出/etc/passwd文件的统计信息:

    $ wc /etc/passwd
    

    分别只输出行数、单词数、字节数、字符数和输入文本中最长一行的字节数:

    # 行数
    $ wc -l /etc/passwd
    # 单词数
    $ wc -w /etc/passwd
    # 字节数
    $ wc -c /etc/passwd
    # 字符数
    $ wc -m /etc/passwd
    # 最长行字节数
    $ wc -L /etc/passwd

    这个命令前面我们也是用过多次,功能很简单就是将输入按照一定方式排序,然后再输出,它支持的排序有按字典排序,数字排序,按月份排序,随机排序,反转排序,指定特定字段进行排序等等。

    默认为字典排序:

    $ cat /etc/passswd | sort
    

    反转排序:

    $ cat /etc/passwd | sort -r
    

    按特定字段排序:

    $ cat /etc/passwd | sort -t':' -k 3
    

    上面的-t参数用于指定字段的分隔符,这里是以":"作为分隔符;-k 字段号用于指定对哪一个字段进行排序。这里/etc/passwd文件的第三个字段为数字,默认情况下是一字典序排序的,如果要按照数字排序就要加上-n参数:

    $ cat /etc/passwd | sort -t':' -k 3 -n

    4、常用快捷键

    按键作用
    Tab 进行命令补全
    Ctrl+c 强行终止当前程序
    Ctrl+d 键盘输入结束或退出终端
    Ctrl+s 暂定当前程序,暂停后按下任意键恢复运行
    Ctrl+z 将当前程序放到后台运行,恢复到前台为命令fg
    Ctrl+a 将光标移至输入行头,相当于Home
    Ctrl+e 将光标移至输入行末,相当于End
    Ctrl+k 删除从光标所在位置到行末
    Alt+Backspace 向前删除一个单词
    Shift+PgUp 将终端显示向上滚动
    Shift+PgDn 将终端显示向下滚动

    键盘上的方向

    历史输入命令

    5、通配符是一种特殊语句,主要有星号(*)和问号(?),用来对对字符串进行模糊匹配(比如文件名,参数名)。终端里面输入的通配符是由 Shell 处理的,它只会出现在命令的“参数值”里。当 Shell 在“参数值”中遇到了通配符时,Shell 会将其当作路径或文件名去在磁盘上搜寻可能的匹配:若符合要求的匹配存在,则进行代换(路径扩展);否则就将该通配符作为一个普通字符传递给“命令”,然后再由命令进行处理。总之,通配符 实际上就是一种 Shell 实现的路径扩展功能。在通配符被处理后, Shell 会先完成该命令的重组,然后再继续处理重组后的命令,直至执行该命令。

    Shell 常用通配符:

    字符含义
    * 匹配 0 或多个字符
    ? 匹配任意一个字符
    [list] 匹配 list 中的任意单一字符
    [!list] 匹配 除list 中的任意单一字符以外的字符
    [c1-c2] 匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z]
    {string1,string2,...} 匹配 sring1 或 string2 (或更多)其一字符串
    {c2..c2} 匹配 c1-c2 中全部字符 如{1..10}


    6、 学会在命令行中获取帮助

    man 命令:用户可以通过执行 man 命令调用手册页。$ man <command_name>

    手册通常被分为8个区段,安排如下:

    区段说明
    1 一般命令
    2 系统调用
    3 库函数,涵盖了C标准函数库
    4 特殊文件(通常是/dev中的设备)和驱动程序
    5 文件格式和约定
    6 游戏和屏保
    7 杂项
    8 系统管理命令和守护进程

    要查看相应区段的内容,就在 man 后面加上相应区段的数字即可,如:$ man printf

    man 中使用搜索,/<你要搜索的关键字>,使用n键切换到下一个关键字所在处,shift+n为上一个关键字所在处。使用Space(空格键)翻页,Enter(回车键)向下滚动一行,或者使用j,k(vim编辑器的移动键)进行向前向后滚动一行。按下h键为显示使用帮助(因为man使用less作为阅读器,实为less工具的帮助),按下q退出。详获取细的帮助,使用info命令,快速查看具体参数的作用,使用--help参数。

     

    实验二作业

    1、banner安装

    2、banner显示

    规定格式显示:'-w'参数指定打印宽度,因为我们的环境在屏幕中显示比较小,必须要加上宽度限制。 

    3、toilet的安装及操作

    安装过程:

    显示过程:

    4、figlet的安装与操作

     figlet安装:

    figlet操作:

    实验三             用户及文件权限管理

    实验介绍:Linux 中创建、删除用户,及用户组等操作;Linux 中的文件权限设置。

    一、Linux 用户管理

    1、查看用户:

    第一列表示打开当前伪终端的用户的用户名(要查看当前登录用户的用户名,去掉空格直接使用 whoami 即可);第二列的 pts/0 中 pts 表示伪终端(伪终端就是当你在图形用户界面使用 /dev/tty7 时每打开一个终端就会产生一个伪终端,所谓伪是相对于 /dev/tty设备而言的),pts/0 后面那个数字就表示打开的伪终端序号;第三列则表示当前伪终端的启动时间。

    who 命令其它常用参数

    参数说明
    -a 打印能打印的全部
    -d 打印死掉的进程
    -m am i,mom likes
    -q 打印当前登录用户数及用户名
    -u 打印当前登录用户登录信息
    -r 打印运行等级

    2、创建用户

    root权限:是 Linux 和 UNIX 系统中的超级管理员用户帐户,该帐户拥有整个系统至高无上的权力,可以操作所有对象。

    sudo命令两个大前提:一是你要知道当前登录用户的密码,二是当前用户必须在 sudo 用户组。 

    默认为新用户创建 home 目录:$ ls /home

    切换登录用户:$ su -l lilei

    3、用户组

     (1)groups命令:  $ groups shiyanlou

    其中冒号之前表示用户,后面表示该用户所属的用户组。每次新建用户如果不指定用户组的话,默认会自动创建一个与用户名相同的用户组。默认情况下在sudo用户组里的可以使用sudo命令获得root权限。

     (2)查看/etc/group文件:   $ cat /etc/group | sort

     cat 命令用于读取指定文件的内容并打印到终端输出; | sort 表示将读取的文本进行一个字典排序再输出

    (3)etc/group 文件格式说明

    /etc/group 的内容包括用户组(Group)、用户组口令、GID 及该用户组所包含的用户(User),每个用户组一条记录。

    格式如下:group_name:password:GID:user_list

     password 字段为 'x',表示密码不可见而已。

    将其它用户加入 sudo 用户组,默认情况下新创建的用户是不具有 root 权限的,也不在 sudo 用户组。

    $ su -l scn     $ sudo ls

    使用 usermod 命令为用户添加用户组,使用该命令需有 root 权限,可以直接使用 root 用户为其它用户添加用户组,或者用其它已经在 sudo 用户组的用户使用 sudo 命令获取权限来执行该命令。用 shiyanlou 用户执行 sudo 命令将 scn 添加到 sudo 用户组,让它也可以使用 sudo 命令获得 root 权限

    $ su shiyanlou
    $ groups scn
    $ sudo usermod -G sudo scn
    $ groups scn

    4、删除用户

    二、Linux 文件权限

    1、查看文件权限

    (1)ls 命令:列出并显示当前目录下的文件。

    使用较长格式列出文件:$ ls -l

    软链接等同于 Windows 上的快捷方式;

    设备文件( /dev 目录下有各种设备文件,大都跟具体的硬件设备相关)

    (2)文件权限:

    读权限,表示你可以使用 cat <file name> 之类的命令来读取某个文件的内容;

    写权限,表示你可以编辑和修改某个文件;

    执行权限,通常指可以运行的二进制程序文件或者脚本文件,如同 Windows 上的 'exe' 后缀的文件,不过 Linux 上不是通过文件后缀名来区分文件的类型。

    一个目录要同时具有读权限和执行权限才可以打开,而一个目录要有写权限才允许在其中创建其它文件,这是因为目录文件实际保存着该目录里面的文件的列表等信息。

    所属用户组权限,是指你所在的用户组中的所有其它用户对于该文件的权限。

    (3)连接数:链接到该文件所在的 inode 结点的文件名数目。

    (4)文件大小:以 inode 结点大小为单位来表示的文件大小, ls 加上 -lh 参数:更直观的查看文件的大小。

    (5)ls 命令的常用用法:显示除了 '.'(当前目录),'..' 上一级目录之外的所有包含隐藏文件(Linux 下以 '.' 开头的文件为隐藏文件)

    $ ls -A:

    $ ls -Al:

    $ ls -dl <目录名>:查看某一个目录的完整属性,而不是显示目录里面的文件属性

    $ ls -AsSh:显示所有文件大小

    其中小 s 为显示文件大小,大 S 为按文件大小排序。

    2、变更文件所有者

    使用以下命令变更文件所有者为 shiyanlou :

    $ cd /home/scn
    $ ls iphone6
    $ sudo chown shiyanlou iphone6
    $ cp iphone6 /home/shiyanlou

    3、修改文件权限

    方式一:二进制数字表示

    每个文件的三组权限(拥有者,所属用户组,其他用户,记住这个顺序是一定的)就对应这一个 "rwx",也就是一个 '7' ,要将文件“iphone6”的权限改为只有我自己可以用:

    方式二:加减赋值操作

    'g''o'还有'u',分别表示group,others,user,'+','-' 就分别表示增加和去掉相应的权限。

    实验三作业

    1、添加一个用户loutest,使用sudo创建文件/opt/forloutest,设置成用户loutest可以读写。截图并把操作过程写入实验报告。

     

    实验三遇到的问题及解决

    1、出现如图所示问题

    原因及解决办法:

    创建用户需要 root 权限,要用到 sudo 这个命令。该命令有两个大前提,一是你要知道当前登录用户的密码,二是当前用户必须在 sudo 用户组。而由于我的实验三实验是在两天中完成的,之前创建的用户,随着虚拟机的关闭而消失,所以会出现这个故障,需要先重新创建用户才能解决。

    2、问题如下图

     原因及解决办法:

     实验四             Linux 目录结构及文件基本操作

    实验介绍

    Linux 的文件组织目录结构; 相对路径和绝对路径;对文件的移动、复制、重命名、编辑等操作。

    一、Linux 目录结构

     Linux 的目录与 Windows 的目录的区别:实现机制完全不同,目录与存储介质的关系不同。

    目录与存储介质(磁盘,内存,DVD 等)的关系不同体现在,以往的 Windows 一直是以存储介质为主的,主要以盘符(C 盘,D 盘...)及分区的来实现文件管理。然而 UNIX/Linux 恰好相反,UNIX 是以目录为主的,Linux 也继承了这一优良特性。 Linux 是以树形目录结构的形式来构建整个系统的,可以理解为一个用户可操作系统的骨架。虽然本质上无论是目录结构还是操作系统内核都是存储在磁盘上的,但从逻辑上来说 Linux 的磁盘是“挂在”(挂载在)目录上的,每一个目录不仅能使用本地磁盘分区的文件系统,也可以使用网络上的文件系统。举例来说,可以利用网络文件系统(Network File System,NFS)服务器载入某特定目录等。

    1.FHS 标准(文件系统层次结构标准)

    FHS 定义了系统中每个区域的用途、所需要的最小构成的文件和目录,同时还给出了例外处理与矛盾处理。

    FHS 定义了两层规范,第一层是, / 下面的各个目录应该要放什么文件数据,例如 /etc 应该要放置设置文件,/bin 与 /sbin 则应该要放置可执行文件等等。

    第二层则是针对 /usr 及 /var 这两个目录的子目录来定义。例如 /var/log 放置系统登录文件、/usr/share 放置共享数据等等。

    FHS_2.3 标准文档

    执行如下命令:$ tree /

    目录定义为四种交互作用的形态,如下表所示:

    2.目录路径

    路径

    cd 命令:可以切换目录, . 表示当前目录,.. 表示上一级目录(使用 ls -a 命令查看隐藏文件), - 表示上一次所在目录,通常表示当前用户的"home"目录。使用 pwd 命令可以获取当前所在路径(绝对路径)。

    进入上一级目录:cd ..

    进入你的“home”目录:cd ~        # 或者 cd /home/<你的用户名>

    使用 pwd 获取当前路径:pwd

    绝对路径

    关于绝对路径,简单地说就是以根"/"目录为起点的完整路径,以你所要到的目录为终点,表现形式如: /usr/local/bin,表示根目录下的 usr 目录中的 local 目录中的 bin 目录。

    相对路径

    相对路径,也就是相对于你当前的目录的路径,相对路径是以当前目录 . 为起点,以你所要到的目录为终点,表现形式如: usr/local/bin (这里假设你当前目录为根目录)。 usr 目录为 / 目录下的子目录,是可以省略这个 . 的;如果是当前目录的上一级目录,则需要使用 .. ,比如你当前目录为“home”目录,根目录就应该表示为 ../../ ,表示上一级目录("home"目录)的上一级目录("/"目录)。

    下面我们以你的"home"目录为起点,分别以绝对路径和相对路径的方式进入/usr/local/bin 目录:

    # 绝对路径
    $ cd /usr/local/bin
    # 相对路径
    $ cd ../../usr/local/bin
    

    提示:在进行目录切换的过程中请多使用 Tab 键自动补全,可避免输入错误,连续按两次Tab可以显示全部候选结果

    二、Linux 文件的基本操作

    1.新建

    新建空白文件

    touch 命令,主要是来更改已有文件的时间戳的(比如,最近访问时间,最近修改时间),但其在不加任何参数的情况下,只指定一个文件名,则可以创建一个为指定文件名的空白文件(不会覆盖已有同名文件),当然你也可以同时指定该文件的时间戳。

    创建名为 test 的空白文件,因为在其他目录没有权限,所以需要先 cd ~ 切换回用户的/home/shiyanlou 目录:cd ~   $ touch test

    新建目录

    使用 mkdir(make directories)命令可以创建一个空目录,也可同时指定创建目录的权限属性

    创建名为"mydir"的空目录:

    $ mkdir mydir
    

    使用 -p 参数,同时创建父目录(如果不存在该父目录),如下我们同时创建一个多级目录(这在有时候安装软件,配置安装路径时非常有用):

    $ mkdir -p father/son/grandson
    

    后面的目录路径,以绝对路径的方式表示也是可以的。

    2.复制

    复制文件

    使用cp(copy)命令复制一个文件或目录到指定目录。将之前创建的"test"文件复制到"/home/shiyanlou/father/son/grandson"目录中:

    $ cp test father/son/grandson

    复制目录

    如果直接使用cp命令,复制一个目录的话,会出现错误。

    要成功复制目录需要加上-r或者-R参数,表示递归复制,就是说有点“株连九族”的意思:

    $ cp -r father family
    

    3.删除

    删除文件

    使用rm(remove files or directories)命令,删除一个文件或目录:$ rm test

    有时候你会遇到想要删除一些为只读权限的文件,直接使用rm删除会显示一个提示:

    你如果想忽略这提示,直接删除文件,可以使用-f参数强制删除:$ rm -f test

    删除目录

    跟复制目录一样,要删除一个目录,也需要加上-r-R参数:  $ rm -r family

    4.移动文件与文件重命名

    移动文件

    使用mv(move or rename files)命令,移动文件(剪切)。将文件"file1"移动到"Documents"目录mv 源目录文件 目的目录$ mv file1 Documents

    重命名文件

    将文件"file1"重命名为"myfile" mv 旧的文件名 新的文件名$ mv file1 myfile

    批量重命名

    rename命令:可以批量重命名

    # 使用通配符批量创建 5 个文件  $ touch file{1..5}.txt
    
    # 批量将这 5 个后缀为 .txt 的文本文件重命名为以 .c 为后缀的文件   $ rename 's/\.txt/\.c/' *.txt
    
    # 批量将这 5 个文件,文件名改为大写   $ rename 'y/a-z/A-Z/' *.c
    

    简单解释下上面的命令,rename是先使用第二个参数的通配符匹配所有后缀为.txt的文件,然后使用第一个参数提供的正则表达式将匹配的这些文件的.txt后缀替换为.c。

    5.查看文件

    使用cat,tacnl命令查看文件

    这两个命令都是用来打印文件内容到标准输出(终端),其中cat为正序显示,tac倒序显示。

    标准输入输出:当我们执行一个 shell 命令行时通常会自动打开三个标准文件,即标准输入文件(stdin),默认对应终端的键盘;标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应被重定向到终端的屏幕,以便我们能直接看到输出内容。进程将从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中。

    比如我们要查看之前从"/etc"目录下拷贝来的passwd文件:$ cat passwd

    可以加上-n参数显示行号:$ cat -n passwd

    nl命令,添加行号并打印,这是个比cat -n更专业的行号打印命令。

    这里简单列举它的常用的几个参数:

    -b : 指定添加行号的方式,主要有两种:
        -b a:表示无论是否为空行,同样列出行号("cat -n"就是这种方式)
        -b t:只列出非空行的编号并列出(默认为这种方式)
    -n : 设置行号的样式,主要有三种:
        -n ln:在行号字段最左端显示
        -n rn:在行号字段最右边显示,且不加 0
        -n rz:在行号字段最右边显示,且加 0
    -w : 行号字段占用的位数(默认为 6 位)

    使用moreless命令分页查看文件

    cat :用来快速查看一个文件内容;moreless:"阅读"文件的内容,比如说"man"手册内部就是使用的 less 来显示内容。其中more命令比较简单,只能向一个方向滚动,而"less"为基于"more"和"vi"(一个强大的编辑器,我们有单独的课程来让你学习)开发,功能更强大。

    使用more工具打开passwd文件:

    $ more passwd
    

     

    打开后默认只显示一屏内容,终端底部显示当前阅读的进度(百分比)。可以使用Enter键向下滚动一行,使用Space键向下滚动一屏,按下h显示帮助,q退出。

    使用headtail命令查看文件

    tail命令:只查看的头几行(默认为10行,不足10行则显示全部)和尾几行。$ tail /etc/passwd

    甚至更直接的只看一行, 加上-n参数,后面紧跟行数:$ tail -n 1 /etc/passwd

     

    关于tail命令,参数-f,可以实现不停地读取某个文件的内容并显示。

    6.查看文件类型

    前面我提到过,在 Linux 下面文件的类型不是根据文件后缀来判断的,我们通常使用file命令可以查看文件的类型:

    $ file /bin/ls
    

     

    这表示这是一个可执行文件,运行在 64 位平台,并使用了动态链接文件(共享库)。

    7.编辑文件——编辑器(vim)

    在 Linux 下面编辑文件通常我们会直接使用专门的命令行编辑器比如(emacs,vim,nano)。如果你想更加快速的入门,你可以直接使用 Linux 内部的 vim 学习教程,输入如下命令即可开始:$ vimtutor

    实验四作业

    实验四遇到的问题

    1、问题如下图

    错误原因及解决:

    实验五                  环境变量与文件查找

    实验介绍

    本节实验介绍环境变量的作用与用法,及几种搜索文件的方法。学会这些技巧高效地使用 Linux。

    一、环境变量

    1、变量

    declare命令:创建变量      如:$ declare tmp

    =号赋值运算符:为变量赋值    如:$ tmp=shiyanlou

    echo命令和$符号:读取变量的值     如:$ echo $tmp

    注意:$符号用于表示引用一个变量的值,初学者经常会忘记输入;关于变量名,并不是任何形式的变量名都是可用的,变量名只能是英文字母,数字或者下划线,且不能以数字作为开头。

     

    通常我们会涉及到的环境变量有三种:

    • 当前 Shell 进程私有用户自定义变量,如上面我们创建的 temp 变量,只在当前 Shell 中有效。
    • Shell 本身内建的变量。
    • 从自定义变量导出的环境变量。

    也有三个与上述三种环境变量相关的命令,setenvexport。这三个命令很相似,都可以用于打印相关环境变量,区别在于涉及的是不同范围的环境变量,详见下表:

    命令说明
    set 显示当前 Shell 所有环境变量,包括其内建环境变量(与 Shell 外观等相关),用户自定义变量及导出的环境变量
    env 显示与当前用户相关的环境变量,还可以让命令在指定环境中运行
    export 显示从 Shell 中导出成环境变量的变量,也能通过它将自定义变量导出为环境变量

     关于环境变量,可以简单的理解成在当前进程的子进程是否有效,有效则为环境变量,否则不是。

     使用vimdiff工具比较一下它们之间的差别:上述操作将命令输出通过管道|使用sort命令排序,再重定向到对象文本文件中。

    export命令:先在 Shell 中设置一个变量temp=shiyanlou,然后再新创建一个子 Shell 查看temp变量的值:

    注意:为了与普通变量区分,通常我们习惯将环境变量名设为大写

    3、命令的查找路径与顺序

    Shell 通过环境变量PATH来进行搜索的,PATH里面保存了Shell中执行命令的搜索路径。

    查看PATH环境变量的内容:echo $PATH

    默认情况下你会看到如下输出:

    创建一个 Shell 脚本文件:$ vim hello_shell.sh

    在脚本中添加如下内容,保存并退出(注意不要省掉第一行,这不是注释,论坛有用户反应会有语法错误,就是因为没有了第一行):

    
    

    为文件添加可执行权限:chmod 755 hello_shell.sh

    执行脚本$ ./hello_shell.sh

    创建一个 C 语言"hello world"程序:

    使用 gcc 生成可执行文件:$ gcc -o hello_world hello_world.c

    gcc 生成二进制文件默认具有可执行权限,不需要修改

    在 shiyanlou 家目录创建一个mybin目录,并将上述 hello_shell.sh 和 hello_world 文件移动到其中:

    $ mkdir mybin
    $ mv hello_shell.sh hello_world mybin/
    

    现在你可以在mybin目录中分别运行你刚刚创建的两个程序:

    $ cd mybin
    $ ./hello_shell.sh
    $ ./hello_world

    要将命令所在路径添加到PATH环境变量。

    4.添加自定义路径到“PATH”环境变量

    在前面我们应该注意到PATH里面的路径是以作为分割符,所以我们可以这样添加自定义路径:PATH=$PATH:/home/shiyanlou/mybin

    注意这里一定要使用绝对路径

    在每个用户的 home 目录中有一个 Shell 每次启动时会默认执行一个配置脚本,以初始化环境,包括添加一些用户自定义环境变量等等。zsh 的配置文件是.zshrc,相应 Bash 的配置文件为.bashrc。它们在etc下还都有一个或多个全局的配置文件,不过我们一般只修改用户目录下的配置文件。

    我们可以简单的使用下面命令直接添加内容到.zshrc中:$ echo "PATH=$PATH:/home/shiyanlou/mybin" >> .zshrc

    上述命令中>>表示将标准输出以追加的方式重定向到一个文件中,注意前面用到的>是以覆盖的方式重定向到一个文件中,使用的时候一定要注意分辨。在指定文件不存在的情况下都会创建新的文件。

    5.修改和删除已有变量

    变量修改

    变量的修改有以下几种方式:

    变量设置方式说明
    ${变量名#匹配字串} 从头向后开始匹配,删除符合匹配字串的最短数据
    ${变量名##匹配字串} 从头向后开始匹配,删除符合匹配字串的最长数据
    ${变量名%匹配字串} 从尾向前开始匹配,删除符合匹配字串的最短数据
    ${变量名%%匹配字串} 从尾向前开始匹配,删除符合匹配字串的最长数据
    ${变量名/旧的字串/新的字串} 将符合旧字串的第一个字串替换为新的字串
    ${变量名//旧的字串/新的字串} 将符合旧字串的全部字串替换为新的字串

    比如要修改我们前面添加到 PATH 的环境变量。为了避免操作失误导致命令找不到,我们先将 PATH 赋值给一个新的自定义变量 path:

    
    

    变量删除

    可以使用unset命令删除一个环境变量:unset temp

    6.如何让环境变量立即生效

    source命令:source .zshrc

    source命令还有一个别名就是.,注意与表示当前路径的那个点区分开,虽然形式一样,但作用和使用方式一样,上面的命令如果替换成.的方式就该是$ . ./.zshrc

    注意第一个点后面有一个空格,而且后面的文件必须指定完整的绝对或相对路径名,source 则不需要。

    二、搜索文件

    与搜索相关的命令有:whereis,which,find,locate

    • whereis简单快速    $whereis who

    你会看到它找到了三个路径,两个可执行文件路径和一个 man 在线帮助文件所在路径,这个搜索很快,因为它并没有从硬盘中依次查找,而是直接从数据库中查询。whereis只能搜索二进制文件(-b),man帮助文件(-m)和源代码文件(-s)。如果想要获得更全面的搜索结果可以使用locate命令。

    • locate快而全

    通过"/var/lib/mlocate/mlocate.db"数据库查找,系统会使用定时任务每天自动执行updatedb命令更新一次,需要手动执行一次updatedb命令(在我们的环境中必须先执行一次该命令)。它可以用来查找指定目录下的不同文件类型,如查找 /etc 下所有以 sh 开头的文件:$ locate /etc/sh

    注意,它不只是在 etc 目录下查找并会自动递归子目录进行查找

    查找 /usr/share/ 下所有 jpg 文件:

    $ locate /usr/share/\*.jpg


    注意要添加*号前面的反斜杠转义,否则会无法找到

    如果想只统计数目可以加上-c参数,-i参数可以忽略大小写进行查找,whereis 的-b,-m-s同样可以是使用。

    • which小而精

    which本身是 Shell 内建的一个命令,我们通常使用which来确定是否安装了某个指定的软件,因为它只从PATH环境变量指定的路径中去搜索命令:

    $ which man
    
    • find精而细

    find应该是这几个命令中最强大的了,它不但可以通过文件类型、文件名进行查找而且可以根据文件的属性(如文件的时间戳,文件的权限等)进行搜索。find命令强大到,要把它将明白至少需要单独好几节课程才行,我们这里只介绍一些常用的内容。

    在指定目录下搜索指定文件名的文件:

    $ find /etc/ -name interfaces

    注意 find 命令的路径是作为第一个参数的, 基本命令格式为 find [path] [option] [action]

    与时间相关的命令参数:

    参数说明
    -atime 最后访问时间
    -ctime 创建时间
    -mtime 最后修改时间

    下面以-mtime参数举例:

    • -mtime n: n 为数字,表示为在n天之前的”一天之内“修改过的文件
    • -mtime +n: 列出在n天之前(不包含n天本身)被修改过的文件
    • -mtime -n: 列出在n天之前(包含n天本身)被修改过的文件
    • newer file: file为一个已存在的文件,列出比file还要新的文件名

    列出 home 目录中,当天(24 小时之内)有改动的文件:

    $ find ~ -mtime 0
    

    列出用户家目录下比Code文件夹新的文件:

    $ find ~ -newer /home/shiyanlou/Code

    实验五作业 

    《黑客帝国》电影里满屏幕代码的“数字雨”,在 Linux 里面你也可以轻松实现这样的效果,你只需要一个命令cmatrix

    实验六                   文件打包与压缩

    实验介绍

    Linux 上常用的 压缩/解压 工具,介绍了 zip,rar,tar 的使用。

    一、文件打包和解压缩

    常见常用的压缩包文件格式:*.zip,*.rar,*.7z, Linux 上还有*.gz,*.xz,*.bz2,*.tar,*.tar.gz,*.tar.xz,*tar.bz2,简单介绍如下:

    文件后缀名说明
    *.zip zip程序打包压缩的文件
    *.rar rar程序压缩的文件
    *.7z 7zip程序压缩的文件
    *.tar tar程序打包,未压缩的文件
    *.gz gzip程序(GNU zip)压缩的文件
    *.xz xz程序压缩的文件
    *.bz2 bzip2程序压缩的文件
    *.tar.gz tar打包,gzip程序压缩的文件
    *.tar.xz tar打包,xz程序压缩的文件
    *tar.bz2 tar打包,bzip2程序压缩的文件
    *.tar.7z tar打包,7z程序压缩的文件

    1.zip压缩打包程序

    • 使用zip打包文件夹:

    上面命令将 shiyanlou 的 home 目录打包成一个文件,并查看了打包后文件的大小和类型。第一行命令中,-r参数表示递归打包包含子目录的全部内容,-q参数表示为安静模式,即不向屏幕输出信息,-o,表示输出文件,需在其后紧跟打包输出文件名。后面使用du命令查看打包后文件的大小(后面会具体说明该命令)。

    • 设置压缩级别为9和1(9最大,1最小),重新打包:
    • $ zip -r -9 -q -o shiyanlou_9.zip /home/shiyanlou -x ~/*.zip
    • $ zip -r -1 -q -o shiyanlou_1.zip /home/shiyanlou -x ~/*.zip

    这里添加了一个参数用于设置压缩级别-[1-9],1表示最快压缩但体积大,9表示体积最小但耗时最久。最后那个-x是为了排除我们上一次创建的 zip 文件,否则又会被打包进这一次的压缩文件中,注意:这里只能使用绝对路径,否则不起作用

    我们再用du命令分别查看默认压缩级别、最低、最高压缩级别及未压缩的文件的大小:$ du -h -d 0 *.zip ~ | sort

    通过man 手册可知:

    • h, --human-readable

    • d, --max-depth(所查看文件的深度)

    • 创建加密zip包

    使用-e参数可以创建加密压缩包:$ zip -r -e -o shiyanlou_encryption.zip /home/shiyanlou

    注意: 关于zip命令,因为 Windows 系统与 Linux/Unix 在文本文件格式上的一些兼容问题,比如换行符(为不可见字符),在 Windows 为 CR+LF(Carriage-Return+Line-Feed:回车加换行),而在 Linux/Unix 上为 LF(换行),需要对命令做一些修改:$ zip -r -l -o shiyanlou.zip /home/shiyanlou

    需要加上-l参数将LF转换为CR+LF

     

    2.使用unzip命令解压缩zip文件

    shiyanlou.zip解压到当前目录:

    $ unzip shiyanlou.zip
    

    使用安静模式,将文件解压到指定目录:

    $ unzip -q shiyanlou.zip -d ziptest
    

    上述指定目录不存在,将会自动创建。如果你不想解压只想查看压缩包的内容你可以使用-l参数:

    $ unzip -l shiyanlou.zip

    注意: 使用unzip解压文件时我们同样应该注意中文编码的问题,通常 Windows 系统上面创建的压缩文件,如果有有包含中文的文档或以中文作为文件名的文件时默认会采用 GBK 或其它编码,而 Linux 上面默认使用的是 UTF-8 编码,直接解压的话可能会出现中文乱码的问题,我们可以在解压时指定编码类型。

    使用-O(英文字母,大写o)参数指定编码类型:unzip -O GBK 中文压缩文件.zip

    3.rar打包压缩命令

    rar也是 Windows 上常用的一种压缩文件格式,在 Linux 上可以使用rarunrar工具分别创建和解压 rar 压缩包。

    • 安装rarunrar工具:
    $ sudo apt-get update
    $ sudo apt-get install rar unrar
    
    • 从指定文件或目录创建压缩包或添加文件到压缩包:
    $ rm *.zip
    $ rar a shiyanlou.rar .

    上面的命令使用a参数添加一个目录到一个归档文件中,如果该文件不存在就会自动创建。

    注意:rar 的命令参数没有-,如果加上会报错。

    • 从指定压缩包文件中删除某个文件:$ rar d shiyanlou.rar .zshrc

    • 查看不解压文件:$ rar l shiyanlou.rar

    • 使用unrar解压rar文件

    全路径解压:$ unrar x shiyanlou.rar

    去掉路径解压:$ mkdir tmp   $ unrar e shiyanlou.rar tmp/

    4.tar打包工具

    在 Linux 上面更常用的是tar工具,tar 原本只是一个打包工具,只是同时还是实现了对 7z,gzip,xz,bzip2 等工具的支持,压缩工具本身只能实现对文件或目录(单独压缩目录中的文件)的压缩,没有实现对文件的打包压缩。tar 的解压和压缩都是同一个命令,只需参数不同。

    下面先掌握tar命令一些基本的使用方式,即不进行压缩只是进行打包(创建归档文件)和解包的操作。

    • 创建一个 tar 包:$ tar -cf shiyanlou.tar ~

    -c表示创建一个 tar 包文件,-f用于指定创建的文件名,注意文件名必须紧跟在-f参数之后,比如不能写成tar -fc shiyanlou.tar,可以写成tar -f shiyanlou.tar -c ~。你还可以加上-v参数以可视的的方式输出打包的文件。上面会自动去掉表示绝对路径的/,你也可以使用-P保留绝对路径符。

    • 解包一个文件(-x参数)到指定路径的已存在目录(-C参数):$ mkdir tardir    $ tar -xf shiyanlou.tar -C tardir
    • 只查看不解包文件-t参数:$ tar -tf shiyanlou.tar

    • 保留文件属性和跟随链接(符号链接或软链接),有时候我们使用tar备份文件当你在其他主机还原时希望保留文件的属性(-p参数)和备份链接指向的源文件而不是链接本身(-h参数):$ tar -cphf etc.tar /etc

    对于创建不同的压缩格式的文件,对于tar来说是相当简单的,需要的只是换一个参数,这里我们就以使用gzip工具创建*.tar.gz文件为例来说明。

    • 我们只需要在创建 tar 文件的基础上添加-z参数,使用gzip来压缩文件:$ tar -czf shiyanlou.tar.gz ~

    • 解压*.tar.gz文件:$ tar -xzf shiyanlou.tar.gz

    现在我们要使用其他的压缩工具创建或解压相应文件只需要更改一个参数即可:

    压缩文件格式参数
    *.tar.gz -z
    *.tar.xz -J
    *tar.bz2 -j

    实验六作业

    1、

    实验六遇到的问题

    1、问题如下图所示

    错误原因和解决:

    实验七             文件系统操作与磁盘管理

    实验介绍

    本节实验的文件系统操作的内容十分简单,只会包含几个命令的几个参数的讲解,但掌握这些也将对你在学习 Linux 和实验楼后续其他课程的过程中有极大帮助。

    一、简单文件系统操作

    1.查看磁盘和目录的容量

    使用 df 命令查看磁盘的容量

    $ df
    

    在实验楼的环境中你将看到如下的输出内容:

    但在实际的物理主机上会更像这样:

    环境中的rootfs或者物理主机上的/dev/sda2

    "rootfs" : (Root File System):一个非常简单的 Linux 文件系统用于实现磁盘缓存机制作为动态可调整大小的基于 ram 的文件系统,或者 tmpfs 的一个特殊实例,它作为系统启动时内核载入内存之后,在挂载真正的的磁盘之前的一个临时文件系统。通常的主机会在系统启动后用磁盘上的文件系统替换,只是在一些嵌入式系统中会只存在一个 rootfs ,或者像我们目前遇到的情况运行在虚拟环境中共享主机资源的系统也可能会采用这种方式。

    物理主机上的 /dev/sda2 是对应着主机硬盘的分区,后面的数字表示分区号,数字前面的字母 a 表示第几块硬盘(也可能是可移动磁盘),你如果主机上有多块硬盘则可能还会出现 /dev/sdb,/dev/sdc 这些磁盘设备都会在 /dev 目录下以文件的存在形式。

    1k-blocks表示以磁盘块大小的方式显示容量,后面为相应的以块大小表示的已用和可用容量:$ df -h

    使用 du 命令查看目录的容量

    这个命令前面其实已经用了很多次了:

    # 默认同样以 blocks 的大小展示
    $ du 
    # 加上`-h`参数,以更易读的方式展示
    $ du -h
    

    -d参数指定查看目录的深度

    # 只查看1级目录的信息
    $ du -h -d 0 ~
    # 查看2级
    $ du -h -d 1 ~
    

    du(estimate file space usage)命令与df(report file system disk space usage)只用一字只差,首先就希望注意不要弄混淆了,以可以像我这样从man手册中获取命令的完整描述,记全称就不会搞混了。

    二、简单的磁盘管理

    下面涉及的命令具有一定的危险性,操作不当可能会丢失你的个人数据,初学者建议在虚拟环境中进行操作

    通常情况下,这一小节应该直接将如何挂载卸载磁盘,如何格式化磁盘,如何分区,但如你所见,我们的环境中没东西给你挂,也没东西给你格和分,所以首先我们会先创建一个虚拟磁盘来进行后续的练习操作

    1.创建虚拟磁盘

    dd 命令简介(部分说明来自dd (Unix) wiki))

    dd命令用于转换和复制文件,不过它的复制不同于cp。之前提到过关于 Linux 的很重要的一点,一切即文件,在 Linux 上,硬件的设备驱动(如硬盘)和特殊设备文件(如/dev/zero/dev/random)都像普通文件一样,只要在各自的驱动程序中实现了对应的功能,dd 也可以读取自和/或写入到这些文件。这样,dd也可以用在备份硬件的引导扇区、获取一定数量的随机数据或者空数据等任务中。dd程序也可以在复制时处理数据,例如转换字节序、或在 ASCII 与 EBCDIC 编码间互换。

    dd的命令行语句与其他的 Linux 程序不同,因为它的命令行选项格式为选项=值,而不是更标准的--选项 值-选项=值dd默认从标准输入中读取,并写入到标准输出中,但可以用选项if(input file,输入文件)和of(output file,输出文件)改变。

    我们先来试试用dd命令从标准输入读入用户输入到标准输出或者一个文件:

    # 输出到文件
    $ dd of=test bs=10 count=1 # 或者 dd if=/dev/stdin of=test bs=10 count=1
    # 输出到标准输出
    $ dd if=/dev/stdin of=/dev/stdout bs=10 count=1
    

    上述命令从标准输入设备读入用户输入(缺省值,所以可省略)然后输出到 test 文件,bs(block size)用于指定块大小(缺省单位为 Byte,也可为其指定如'K','M','G'等单位),count用于指定块数量。如上图所示,我指定只读取总共 10 个字节的数据,当我输入了“hello shiyanlou”之后加上空格回车总共 16 个字节(一个英文字符占一个字节)内容,显然超过了设定大小。使用和ducat命令看到的写入完成文件实际内容确实只有 10 个字节(那个黑底百分号表示这里没有换行符),而其他的多余输入将被截取并保留在标准输入。

    前面说到dd在拷贝的同时还可以实现数据转换,那下面就举一个简单的例子:将输出的英文字符转换为大写再写入文件:

    $ dd if=/dev/stdin of=test bs=10 count=1 conv=ucase
    

    使用 dd 命令创建虚拟镜像文件

    通过上面一小节,你应该掌握了dd的基本使用,下面就来使用dd命令来完成创建虚拟磁盘的第一步。

    /dev/zero设备创建一个容量为 256M 的空文件:$ dd if=/dev/zero of=virtual.img bs=1M count=256    $ du -h virtual.img

    使用 mkfs 命令格式化磁盘(我们这里是自己创建的虚拟磁盘镜像)

    你可以在命令行输入 mkfs 然后按下Tab键,你可以看到很多个以 mkfs 为前缀的命令,这些不同的后缀其实就是表示着不同的文件系统,可以用 mkfs 格式化成的文件系统:

    我们可以简单的使用下面的命令来将我们的虚拟磁盘镜像格式化为ext4文件系统: $ mkfs.ext4 virtual.img

     mkfs.ext4 是使用 mke2fs 来完成格式化工作的。查询 Linux 支持的文件系统:ls -l /lib/modules/$(uname -r)/kernel/fs

    使用 mount 命令挂载磁盘到目录树

    用户在 Linux/UNIX 的机器上打开一个文件以前,包含该文件的文件系统必须先进行挂载的动作,此时用户要对该文件系统执行 mount 的指令以进行挂载。通常是使用在 USB 或其他可移除存储设备上,而根目录则需要始终保持挂载的状态。又因为 Linux/UNIX 文件系统可以对应一个文件而不一定要是硬件设备,所以可以挂载一个包含文件系统的文件到目录树。

    Linux/UNIX 命令行的 mount 指令是告诉操作系统,对应的文件系统已经准备好,可以使用了,而该文件系统会对应到一个特定的点(称为挂载点)。挂载好的文件、目录、设备以及特殊文件即可提供用户使用。

    我们先来使用mount来查看下主机已经挂载的文件系统:

    $ sudo mount
    

    输出的结果中每一行表示一个设备或虚拟设备,每一行最前面是设备名,然后是 on 后面是挂载点,type 后面表示文件系统类型,再后面是挂载选项(比如可以在挂载时设定以只读方式挂载等等)。

    那么我们如何挂载真正的磁盘到目录树呢,mount命令的一般格式如下:

    mount [options] [source] [directory]
    

    一些常用操作:

    mount [-o [操作选项]] [-t 文件系统类型] [-w|--rw|--ro] [文件系统源] [挂载点]
    

    我们现在直接来挂载我们创建的虚拟磁盘镜像到/mnt目录:

    $ mount -o loop -t ext4 virtual.img /mnt 
    # 也可以省略挂载类型,很多时候 mount 会自动识别
    
    # 以只读方式挂载
    $ mount -o loop --ro virtual.img /mnt
    # 或者mount -o loop,ro virtual.img /mnt
    

    使用 umount 命令卸载已挂载磁盘

    # 命令格式 sudo umount 已挂载设备名或者挂载点,如:
    $ sudo umount /mnt
    

    不过遗憾的是,由于我们环境的问题(环境中使用的 Linux 内核在编译时没有添加对 Loop device的支持),所以你将无法挂载成功:

    另外关于 loop 设备,你可能会有诸多疑问,那么请看下面来自维基百科/dev/loop的说明:

    在类 UNIX 系统中,/dev/loop(或称vnd (vnode disk)、lofi(循环文件接口))是一种伪设备,这种设备使得文件可以如同块设备一般被访问。

    在使用之前,循环设备必须与现存文件系统上的文件相关联。这种关联将提供给用户一个应用程序接口,接口将允许文件视为块特殊文件(参见设备文件系统)使用。因此,如果文件中包含一个完整的文件系统,那么这个文件就能如同磁盘设备一般被挂载。

    这种设备文件经常被用于光盘或是磁盘镜像。通过循环挂载来挂载包含文件系统的文件,便使处在这个文件系统中的文件得以被访问。这些文件将出现在挂载点目录。如果挂载目录中本身有文件,这些文件在挂载后将被禁止使用。

    使用 fdisk 为磁盘分区(关于分区的一些概念不清楚的用户请参看主引导记录

    同样因为环境原因中没有物理磁盘,也无法创建虚拟磁盘的原因我们就无法实验练习使用该命令了,下面我将以我的物理主机为例讲解如何为磁盘分区。

    # 查看硬盘分区表信息
    $ sudo fdisk -l
    

    输出结果中开头显示了我主机上的磁盘的一些信息,包括容量扇区数,扇区大小,I/O 大小等信息。

    我们重点开一下中间的分区信息,/dev/sda1,/dev/sda2 为主分区分别安装了 Windows 和 Linux 操作系统,/dev/sda3 为交换分区(可以理解为虚拟内存),/dev/sda4 为扩展分区其中包含 /dev/sda5,/dev/sda6,/dev/sda7,/dev/sda8 四个逻辑分区,因为主机上有几个分区之间有空隙,没有对齐边界扇区,所以分区之间的不是完全连续的。

    # 进入磁盘分区模式
    $ sudo fdisk virtual.img
    

    在进行操作前我们首先应先规划好我们的分区方案,这里我将在使用 128M(可用 127M 左右)的虚拟磁盘镜像创建一个 30M 的主分区剩余部分为扩展分区包含 2 个大约 45M 的逻辑分区。

    操作完成后输入p查看结果如下:

    最后不要忘记输入w写入分区表。

    使用 losetup 命令建立镜像与回环设备的关联

    $ sudo losetup /dev/loop0 virtual.img
    # 如果提示设备忙你也可以使用其它的回环设备,"ls /dev/loop*"参看所有回环设备
    
    # 解除设备关联
    $ sudo losetup -d /dev/loop0
    

    然后再使用mkfs格式化各分区(前面我们是格式化整个虚拟磁盘镜像文件或磁盘),不过格式化之前,我们还要为各分区建立虚拟设备的映射,用到kpartx工具,需要先安装:

    $ sudo apt-get install kpartx
    $ sudo kpart kpartx -av /dev/loop0
    
    # 取消映射
    $ sudo kpart kpartx -dv /dev/loop0
    

    接着再是格式化,我们将其全部格式化为 ext4:

    $ sudo mkfs.ext4 -q /dev/mapper/loop0p1
    $ sudo mkfs.ext4 -q /dev/mapper/loop0p5
    $ sudo mkfs.ext4 -q /dev/mapper/loop0p6
    

    格式化完成后在/media目录下新建四个空目录用于挂载虚拟磁盘:

    $ mkdir -p /media/virtualdisk_{1..3}
    
    # 挂载磁盘分区
    $ sudo mount /dev/mapper/loop0p1 /media/virtualdisk_1
    $ sudo mount /dev/mapper/loop0p5 /media/virtualdisk_2
    $ sudo mount /dev/mapper/loop0p6 /media/virtualdisk_3
    
    # 卸载磁盘分区
    $ sudo umount /dev/mapper/loop0p1
    $ sudo umount /dev/mapper/loop0p5
    $ sudo umount /dev/mapper/loop0p6
    

    然后:

    $ df -h

    实验八                  命令执行顺序控制与管道

    实验介绍

    顺序执行、选择执行、管道、cut 命令、grep 命令、wc 命令、sort 命令等,高效率使用 Linux 的技巧。

    一、命令执行顺序的控制

    1.顺序执行多条命令

    通常情况下,我们每次只能在终端输入一条命令,按下回车执行,执行完成后,我们再输入第二条命令,然后再按回车执行…… 你可能会遇到如下使用场景:我需要使用apt-get安装一个软件,然后安装完成后立即运行安装的软件(或命令工具),又恰巧你的主机才更换的软件源还没有更新软件列表(比如之前我们的环境中,每次重新开始实验就得sudo apt-get update,现在已经没有这个问题了),那么你可能会有如下一系列操作:

    $ sudo apt-get update
    # 等待——————————然后输入下面的命令
    $ sudo apt-get install some-tool
    # 等待——————————然后输入下面的命令
    $ some-tool
    

    这时你可能就会想要是我可以一次性输入完,让它自己去一次执行各命令就好了,这就是我们这一小节要解决的问题。

    简单的顺序执行你可以使用;来完成,比如上述操作你可以:

    $ sudo apt-get update;sudo apt-get install some-tool;some-tool
    # 让它自己运行
    

    2.有选择的执行命令

    关于上面的操作,不知你有没有思考过一个问题,如果我们在让它自动顺序执行命令时,前面的命令执行不成功,而后面的命令又依赖与上一条命令的结果,那么就会造成花了时间,最终却得到一个错误的结果,而且有时候直观的看你还无法判断结果是否正确。那么我们需要能够有选择性的来执行命令,比如上一条命令执行成功才继续下一条,或者不成功又该做出其它什么处理,比如我们使用which来查找是否安装某个命令,如果找到就执行该命令,否则什么也不做(虽然这个操作没有什么实际意义,但可帮你更好的理解一些概念):

    $ which cowsay>/dev/null && cowsay -f head-in ohch~
    

    你如果没有安装cowsay,你可以先执行一次上述命令,你会发现什么也没发生,你再安装好之后你再执行一次上述命令,你也会发现一些惊喜。

    上面的&&就是用来实现选择性执行的,它表示如果前面的命令执行结果(不是表示终端输出的内容,而是表示命令执行状态的结果)返回0则执行后面的,否则不执行,你可以从$?环境变量获取上一次命令的返回结果:

    学习过 C 语言的用户应该知道在 C 语言里面&&表是逻辑与,而且还有一个||表示逻辑或,同样 Shell 也有一个||,它们的区别就在于,shell中的这两个符号除了也可用于表示逻辑与和或之外,就是可以实现这里的命令执行顺序的简单控制。||在这里就是与&&相反的控制效果,当上一条命令执行结果为≠0($?≠0)时则执行它后面的命令:

    $ which cowsay>/dev/null || echo "cowsay has not been install, please run 'sudo apt-get install cowsay' to install"
    

    除了上述基本的使用之外,我们还可以结合这&&||来实现一些操作,比如:

    $ which cowsay>/dev/null && echo "exist" || echo "not exist"
    

    我画个流程图来解释一下上面的流程:

    思考

    上面我们讲到将&&||结合起来使用,那么是否以任意顺序都行?比如上面我们是&&在前||在后,反过来可以么?会不会有问题?

    二、管道

    管道是什么,管道是一种通信机制,通常用于进程间的通信(也可通过socket进行网络通信),它表现出来的形式就是将前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin)。

    管道又分为匿名管道和具名管道(这里将不会讨论在源程序中使用系统调用创建并使用管道的情况,它与命令行的管道在内核中实际都是采用相同的机制)。我们在使用一些过滤程序时经常会用到的就是匿名管道,在命令行中由|分隔符表示,|在前面的内容中我们已经多次使用到了。具名管道简单的说就是有名字的管道,通常只会在源程序中用到具名管道。下面我们就将通过一些常用的可以使用管道的"过滤程序"来帮助你熟练管道的使用。

    1.试用

    先试用一下管道,比如查看/etc目录下有哪些文件和目录,使用ls命令来查看:

    $ ls -al /etc
    

    有太多内容,屏幕不能完全显示,这时候可以使用滚动条或快捷键滚动窗口来查看。不过这时候可以使用管道:

    $ ls -al /etc | less
    

    通过管道将前一个命令(ls)的输出作为下一个命令(less)的输入,然后就可以一行一行地看。

    2.cut 命令,打印每一行的某一字段

    打印/etc/passwd文件中以:为分隔符的第1个字段和第6个字段分别表示用户名和其家目录:

    $ cut /etc/passwd -d ':' -f 1,6
    

    打印/etc/passwd文件中每一行的前N个字符:

    # 前五个(包含第五个)
    $ cut /etc/passwd -c -5
    # 前五个之后的(包含第五个)
    $ cut /etc/passwd -c 5-
    # 第五个
    $ cut /etc/passwd -c 5
    # 2到5之间的(包含第五个)
    $ cut /etc/passwd -c 2-5
    

    3.grep 命令,在文本中或 stdin 中查找匹配字符串

    grep命令是很强大的,也是相当常用的一个命令,它结合正则表达式可以实现很复杂却很高效的匹配和查找,不过在学习正则表达式之前,这里介绍它简单的使用,而关于正则表达式后面将会有单独一小节介绍到时会再继续学习grep命令和其他一些命令。

    grep命令的一般形式为:

    grep [命令选项]... 用于匹配的表达式 [文件]...
    

    还是先体验一下,我们搜索/home/shiyanlou目录下所有包含"shiyanlou"的所有文本文件,并显示出现在文本中的行号:

    $ grep -rnI "shiyanlou" ~
    

    -r 参数表示递归搜索子目录中的文件,-n表示打印匹配项行号,-I表示忽略二进制文件。这个操作实际没有多大意义,但可以感受到grep命令的强大与实用。

    当然也可以在匹配字段中使用正则表达式,下面简单的演示:

    # 查看环境变量中以"yanlou"结尾的字符串
    $ export | grep ".*yanlou$"
    

    其中$就表示一行的末尾。

    4. wc 命令,简单小巧的计数工具

    wc 命令用于统计并输出一个文件中行、单词和字节的数目,比如输出/etc/passwd文件的统计信息:

    $ wc /etc/passwd
    

    分别只输出行数、单词数、字节数、字符数和输入文本中最长一行的字节数:

    # 行数
    $ wc -l /etc/passwd
    # 单词数
    $ wc -w /etc/passwd
    # 字节数
    $ wc -c /etc/passwd
    # 字符数
    $ wc -m /etc/passwd
    # 最长行字节数
    $ wc -L /etc/passwd
    

    注意:对于西文字符来说,一个字符就是一个字节,但对于中文字符一个汉字是大于2个字节的,具体数目是由字符编码决定的

    再来结合管道来操作一下,下面统计 /etc 下面所有目录数:

    $ ls -dl /etc/*/ | wc -l
    

    5.sort 排序命令

    这个命令前面我们也是用过多次,功能很简单就是将输入按照一定方式排序,然后再输出,它支持的排序有按字典排序,数字排序,按月份排序,随机排序,反转排序,指定特定字段进行排序等等。

    默认为字典排序:

    $ cat /etc/passswd | sort
    

    反转排序:

    $ cat /etc/passwd | sort -r
    

    按特定字段排序:

    $ cat /etc/passwd | sort -t':' -k 3
    

    上面的-t参数用于指定字段的分隔符,这里是以":"作为分隔符;-k 字段号用于指定对哪一个字段进行排序。这里/etc/passwd文件的第三个字段为数字,默认情况下是一字典序排序的,如果要按照数字排序就要加上-n参数:

    $ cat /etc/passwd | sort -t':' -k 3 -n
    

    6. uniq 去重命令

    uniq命令可以用于过滤或者输出重复行。

    • 过滤重复行

    我们可以使用history命令查看最近执行过的命令(实际为读取${SHELL}_history文件,如我们环境中的~/.zsh_history文件),不过你可能只想查看使用了那个命令而不需要知道具体干了什么,那么你可能就会要想去掉命令后面的参数然后去掉重复的命令:

    $ history | cut -c 8- | cut -d ' ' -f 1 | uniq
    

    然后经过层层过滤,你会发现确是只输出了执行的命令那一列,不过去重效果好像不明显,仔细看你会发现它趋势去重了,只是不那么明显,之所以不明显是因为uniq命令只能去连续重复的行,不是全文去重,所以要达到预期效果,我们先排序:

    $ history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq
    # 或者$ history | cut -c 8- | cut -d ' ' -f 1 | sort -u
    

    这就是 Linux/UNIX 哲学吸引人的地方,大繁至简,一个命令只干一件事却能干到最好。

    • 输出重复行
    # 输出重复过的行(重复的只输出一个)及重复次数
    $ history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq -dc
    # 输出所有重复的行
    $ history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq -D
    九-简单的文本处理
    # 删除 "hello shiyanlou" 中所有的'o','l','h'
    $ echo 'hello shiyanlou' | tr -d 'olh'
    # 将"hello" 中的ll,去重为一个l
    $ echo 'hello' | tr -s 'l'
    # 将输入文本,全部转换为大写或小写输出
    $ cat /etc/passwd | tr '[:lower:]' '[:upper:]'
    # 上面的'[:lower:]' '[:upper:]'你也可以简单的写作'[a-z]' '[A-Z]',当然反过来将大写变小写也是可以的


    # 查看 /etc/protocols 中的不可见字符,可以看到很多 ^I ,这其实就是 Tab 转义成可见字符的符号
    $ cat -A /etc/protocols
    # 使用 col -x 将 /etc/protocols 中的 Tab 转换为空格,然后再使用 cat 查看,你发现 ^I 不见了
    $ cat /etc/protocols | col -x | cat -A


    # 创建两个文件
    $ echo '1 hello' > file1
    $ echo '1 shiyanlou' > file2
    $ join file1 file2
    # 将/etc/passwd与/etc/shadow两个文件合并,指定以':'作为分隔符
    $ sudo join -t':' /etc/passwd /etc/shadow
    # 将/etc/passwd与/etc/group两个文件合并,指定以':'作为分隔符, 分别比对第4和第3个字段
    $ sudo join -t':' -1 4 /etc/passwd -2 3 /etc/group


    $ echo hello > file1
    $ echo shiyanlou > file2
    $ echo www.shiyanlou.com > file3
    $ paste -d ':' file1 file2 file3
    $ paste -s file1 file2 file3


                                十- 数据流重定向
    $ echo 'hello shiyanlou' > redirect 
    $ echo 'www.shiyanlou.com' >> redirect
    $ cat redirect

    EOF
    

    将一个文件作为命令的输入,标准输出作为命令的输出

    $ cat Documents/test.c\~
    

    将echo命令通过管道传过来的数据作为cat命令的输入,将标准输出作为命令的输出

    $ echo 'hi' | cat
    

    将echo命令的输出从默认的标准输出重定向到一个普通文件

    $ echo 'hello shiyanlou' > redirect
    $ cat redirect



    重定向标准输出到文件,这是一个很实用的操作,另一个很实用的操作是将标准错误重定向,标准输出和标准错误都被指向伪终端的屏幕显示,所以我们经常看到的一个命令的输出通常是同时包含了标准输出和标准错误的结果的。比如下面的操作:

    # 使用cat 命令同时读取两个文件,其中一个存在,另一个不存在
    $ cat Documents/test.c\~ hello.c
    # 你可以看到除了正确输出了前一个文件的内容,还在末尾出现了一条错误信息
    # 下面我们将输出重定向到一个文件,根据我们前面的经验,这里将在看不到任何输出了
    $ cat Documents/test.c\~ hello.c > somefile

    遗憾的是,这里依然出现了那条错误信息,这正是因为如我上面说的那样,标准输出和标准错误虽然都指向终端屏幕,实际它们并不一样。那有的时候我们就是要可以隐藏某些错误或者警告,那又该怎么做呢。这就需要用到我们前面讲的文件描述符了:

    # 将标准错误重定向到标准输出,再将标准输出重定向到文件,注意要将重定向到文件写到前面
    $ cat Documents/test.c\~ hello.c >somefile  2>&1
    # 或者只用bash提供的特殊的重定向符号"&"将标准错误和标准输出同时重定向到文件
    $ cat Documents/test.c\~ hello.c &>somefilehell


    你应该可以看出我们前面的重定向操作都只是临时性的,即只对当前命令有效,那如何做到“永久”有效呢,比如在一个脚本中,你需要某一部分的命令的输出全部进行重定向,难道要让你在每个命令上面加上临时重定向的操作嘛,当然不需要,我们可以使用exec命令实现“永久”重定向。exec命令的作用是使用指定的命令替换当前的 Shell,及使用一个进程替换当前进程,或者指定新的重定向:

    # 先开启一个子 Shell
    $ zsh
    # 使用exec替换当前进程的重定向,将标准输出重定向到一个文件
    $ exec 1>somefile
    # 后面你执行的命令的输出都将被重定向到文件中,直到你退出当前子shell,或取消exec的重定向(后面将告诉你怎么做)
    $ ls
    $ exit
    $ cat somefile

    5.创建输出文件描述符

    默认在 Shell 中可以有9个打开的文件描述符,上面我们使用了也是它默认提供的0,1,2号文件描述符,另外我们还可以使用3-8的文件描述符,只是它们默认没有打开而已,你可以使用下面命令查看当前 Shell 进程中打开的文件描述符:

    $ cd /dev/fd/;ls -Al
    

    同样使用exec命令可以创建新的文件描述符:

    $ zsh
    $ exec 3>somefile
    # 先进入目录,再查看,否则你可能不能得到正确的结果,然后再回到上一次的目录
    $ cd /dev/fd/;ls -Al;cd -
    # 注意下面的命令>与&之间不应该有空格,如果有空格则会出错
    $ echo "this is test" >&3
    $ cat somefile
    $ exit

    
                                             十一-正则表达式基础

    什么是正则表达式呢?

    正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为 regex、regexp 或 RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

    许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在 Perl 中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由 UNIX 中的工具软件(例如sedgrep)普及开的。正则表达式通常缩写成“regex”,单数有 regexp、regex,复数有 regexps、regexes、regexen。

    简单的说形式和功能上正则表达式和我们前面讲的通配符很像,不过它们之间又有很大差别,特别在于一些特殊的匹配字符的含义上,希望初学者注意不要将两者弄混淆。

    假设我们有这样一个文本文件,包含"shiyanlou",和"shilouyan"这两个字符串,同样一个表达式:

    shi*
    

    如果这作为一个正则表达式,它将只能匹配 shi,而如果不是作为正则表达式*作为一个通配符,则将同时匹配这两个字符串。这是为什么呢?因为在正则表达式中*表示匹配前面的子表达式(这里就是它前面一个字符)零次或多次,比如它可以匹配"sh","shii","shish","shiishi"等等,而作为通配符表示匹配通配符后面任意多个任意字符,所以它可以匹配"shiyanlou",和"shilouyan"两个字符。

    基本语法:

    一个正则表达式通常被称为一个模式(pattern),为用来描述或者匹配一系列符合某个句法规则的字符串。

    选择

    |竖直分隔符表示选择,例如"boy|girl"可以匹配"boy"或者"girl"

    数量限定

    数量限定除了我们举例用的*,还有+加号,?问号,.点号,如果在一个模式中不加数量限定符则表示出现一次且仅出现一次:

    • +表示前面的字符必须出现至少一次(1次或多次),例如,"goo+gle",可以匹配"gooogle","goooogle"等;
    • ?表示前面的字符最多出现一次(0次或1次),例如,"colou?r",可以匹配"color"或者"colour";
    • *星号代表前面的字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次),例如,“0*42”可以匹配42、042、0042、00042等。

    范围和优先级

    ()圆括号可以用来定义模式字符串的范围和优先级,这可以简单的理解为是否将括号内的模式串作为一个整体。例如,"gr(a|e)y"等价于"gray|grey",(这里体现了优先级,竖直分隔符用于选择a或者e而不是gra和ey),"(grand)?father"匹配father和grandfather(这里体验了范围,?将圆括号内容作为一个整体匹配)。

    语法(部分)

    正则表达式有多种不同的风格,下面列举一些常用的作为 PCRE 子集的适用于perlpython编程语言及grepegrep的正则表达式匹配规则:(由于markdown表格解析的问题,下面的竖直分隔符用全角字符代替,实际使用时请换回半角字符)

    PCRE(Perl Compatible Regular Expressions中文含义:perl语言兼容正则表达式)是一个用 C 语言编写的正则表达式函数库,由菲利普.海泽(Philip Hazel)编写。PCRE是一个轻量级的函数库,比Boost 之类的正则表达式库小得多。PCRE 十分易用,同时功能也很强大,性能超过了 POSIX 正则表达式库和一些经典的正则表达式库。



    
    
    
    
    

    # 打印2-5行
    $ nl passwd | sed -n '2,5p'
    # 打印奇数行
    $ nl passwd | sed -n '1~2p'
    
    
    
    

    awk文本处理语言

    
    

    看到上面的标题,你可能会感到惊异,难道我们这里要学习的是一门“语言”么,确切的说,我们是要在这里学习awk文本处理语言,只是我们并不会在这里学习到比较完整的关于awk的内容,还是因为前面的原因,它太强大了,它的应用无处不在,我们无法在这里以简短的文字描述面面俱到,如果你有目标成为一个linux系统管理员,确实想学好awk,你一不用担心,实验楼会在之后陆续上线linux系统管理员的学习路径,里面会有单独的关于正则表达式,awk,sed等相关课程,敬请期待吧。下面的内容,我们就作为一个关于awk的入门体验章节吧,其中会介绍一些awk的常用操作。

    
    

    1.awk介绍

    
    

    AWK是一种优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一.其名称得自于它的创始人Alfred Aho(阿尔佛雷德·艾侯)、Peter Jay Weinberger(彼得·温伯格)和Brian Wilson Kernighan(布莱恩·柯林汉)姓氏的首个字母.AWK程序设计语言,三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。最简单地说,AWK是一种用于处理文本的编程语言工具。

    
    

    在大多数linux发行版上面,实际我们使用的是gawk(GNU awk,awk的GNU版本),在我们的环境中ubuntu上,默认提供的是mawk,不过我们通常可以直接使用awk命令(awk语言的解释器),因为系统已经为我们创建好了awk指向mawk的符号链接。

    
    

    awk所有的操作都是基于pattern(模式)—action(动作)对来完成的,如下面的形式:

    
    
    $ pattern {action}
    
    
    

    你可以看到就如同很多编程语言一样,它将所有的动作操作用一对{}花括号包围起来。其中pattern通常是是表示用于匹配输入的文本的“关系式”或“正则表达式”,action则是表示匹配后将执行的动作。在一个完整awk操作中,这两者可以只有其中一个,如果没有pattern则默认匹配输入的全部文本,如果没有action则默认为打印匹配内容到屏幕。

    
    

    awk处理文本的方式,是将文本分割成一些“字段”,然后再对这些字段进行处理,默认情况下,awk以空格作为一个字段的分割符,不过这不是固定了,你可以任意指定分隔符,下面将告诉你如何做到这一点。

    
    

    3.awk命令基本格式

    
    
    awk [-F fs] [-v var=value] [-f prog-file | 'program text'] [file...]
    
    
    

    其中-F参数用于预先指定前面提到的字段分隔符(还有其他指定字段的方式) ,-v用于预先为awk程序指定变量,-f参数用于指定awk命令要执行的程序文件,或者在不加-f参数的情况下直接将程序语句放在这里,最后为awk需要处理的文本输入,且可以同时输入多个文本文件。现在我们还是直接来具体体验一下吧。

    
    

    4.awk操作体验

    
    

    先用vim新建一个文本文档

    
    
    $ vim test
    
    
    

    包含如下内容:

    
    
    I like linux
    www.shiyanlou.com
    
    
    
    • 使用awk将文本内容打印到终端
    
    
    # "quote>" 不用输入
    $ awk '{
    > print
    > }' test
    # 或者写到一行
    $ awk '{print}' test

    十二-Linux下载软件安装

    通常 Linux 上的软件安装主要有三种方式:

    
    
    • 在线安装
    • 从磁盘安装deb软件包
    • 从二进制软件包安装
    • 从源代码编译安装
    
    

    这几种安装方式各有优劣,而大多数软件包会采用多种方式发布软件,所以我们常常需要全部掌握这几种软件安装方式,以便适应各种环境。下面将介绍前三种安装方式,从源码编译安装你将在 Linux 程序设计中学习到。

    试想一下,平时我们在使用 Windows 的时候,想要安装一个软件,我们需要在网上去下载对应软件的安装包,接着安装的时候就是不断的去点击下一步,这些流程想必大家已经经历的无数回了,但是在 Linux 下,一个命令加回车,等待一下,软件就安装好了,这就是方便的在线安装软件的方式。在学习这种安装方式之前有一点需要说明的是,在不同的linux发行版上面在线安装方式会有一些差异包括使用的命令及它们的包管理工具,因为我们的开发环境是基于ubuntu的,所以这里我们涉及的在线安装方式将只适用于ubuntu发行版,或其它基于ubuntu的发行版如国内的ubuntukylin(优麒麟),ubuntu又是基于debian的发行版,它使用的是debian的包管理工具dpkg,所以一些操作也适用与debian。而在其它一些采用其它包管理工具的发行版如redhat,centos,fedora等将不适用(redhat和centos使用rpm)

    
    

    apt 包管理工具介绍

    
    

    APT是Advance Packaging Tool(高级包装工具)的缩写,是Debian及其派生发行版的软件包管理器,APT可以自动下载,配置,安装二进制或者源代码格式的软件包,因此简化了Unix系统上管理软件的过程。APT最早被设计成dpkg的前端,用来处理deb格式的软件包。现在经过APT-RPM组织修改,APT已经可以安装在支持RPM的系统管理RPM包。这个包管理器包含以 apt- 开头的的多个工具,如 apt-get apt-cache apt-cdrom 等,在Debian系列的发行版中使用。

    
    

    当你在执行安装操作时,首先apt-get 工具会在本地的一个数据库中搜索关于 w3m 软件的相关信息,并根据这些信息在相关的服务器上下载软件安装,这里大家可能会一个疑问:既然是在线安装软件,为啥会在本地的数据库中搜索?要解释这个问题就得提到几个名词了:

    
    
    • 软件源镜像服务器
    • 软件源
    
    

    我们需要定期从服务器上下载一个软件包列表,使用 sudo apt-get update 命令来保持本地的软件包列表是最新的(有时你也需要手动执行这个操作,比如更换了软件源),而这个表里会有软件依赖信息的记录,对于软件依赖,我举个例子:我们安装 w3m 软件的时候,而这个软件需要 libgc1c2 这个软件包才能正常工作,这个时候 apt-get 在安装软件的时候会一并替我们安装了,以保证 w3m 能正常的工作。

    
    

    3.apt-get

    
    

    apt-get使用各用于处理apt包的公用程序集,我们可以用它来在线安装、卸载和升级软件包等,下面列出一些apt-get包含的常用的一些工具:

    安装软件包

    关于安装,如前面演示的一样你只需要执行apt-get install <软件包名>即可,除了这一点,你还应该掌握的是如何重新安装软件包。 很多时候我们需要重新安装一个软件包,比如你的系统被破坏,或者一些错误的配置导致软件无法正常工作。

    你可以使用如下方式重新安装:

    $ sudo apt-get --reinstall install w3m
    

    另一个你需要掌握的是,如何在不知道软件包完整名的时候进行安装。通常我们是使用Tab键补全软件包名,后面会介绍更好的方法来搜索软件包。有时候你需要同时安装多个软件包,你还可以使用正则表达式匹配软件包名进行批量安装。

    5.软件升级

    # 更新软件源
    $ sudo apt-get update
    # 升级没有依赖问题的软件包
    $ sudo apt-get upgrade
    # 升级并解决依赖关系
    $ sudo apt-get dist-upgrade

    
    
    
    

    软件搜索

    
    

    当自己刚知道了一个软件,想下载使用,需要确认软件仓库里面有没有,就需要用到搜索功能了,命令如下:

    
    
    sudo apt-cache search softname1 softname2 softname3……
    
    
    

    apt-cache 命令则是针对本地数据进行相关操作的工具,search 顾名思义在本地的数据库中寻找有关 softname1 softname2 …… 相关软件的信息。现在我们试试搜索一下之前我们安装的软件 w3m ,如图:

    
    

    使用 dpkg 从本地磁盘安装 deb 软件包

    
    

    1.dpkg 介绍

    
    

    dpkg 是 Debian 软件包管理器的基础,它被伊恩·默多克创建于 1993 年。dpkg 与 RPM 十分相似,同样被用于安装、卸载和供给和 .deb 软件包相关的信息。

    dpkg 本身是一个底层的工具。上层的工具,像是 APT,被用于从远程获取软件包以及处理复杂的软件包关系。"dpkg"是"Debian Package"的简写。

    
    

    我们经常可以在网络上简单以deb形式打包的软件包,就需要使用dpkg命令来安装。

    使用dpkg安装deb软件包

    我们先使用apt-get加上-d参数只下载不安装,下载emacs编辑器的deb包,下载完成后,我们可以查看/var/cache/apt/archives/目录下的内容,如下图:


    然后我们将第一个deb拷贝到home目录下,并使用dpkg安装

    
    
    $ cp /var/cache/apt/archives/emacs24_24.3+1-4ubuntu1_amd64.deb ~
    # 安装之前参看deb包的信息
    $ sudo dpkg -I emacs24_24.3+1-4ubuntu1_amd64.deb
    
    
    

    如你所见,这个包还额外依赖了一些软件包,这意味着,如果主机目前没有这些被依赖的软件包,直接使用dpkg安装可能会存在一些问题,因为dpkg并不能为你解决依赖关系。

    
    
    # 使用dpkg安装
    $ sudo dpkg -i emacs24_24.3+1-4ubuntu1_amd64.deb
    
    
    

    跟前面预料的一样,这里你可能出现了一些错误:


    我们将如何解决这个错误了,这就要用到apt-get了,使用它的-f参数了,修复依赖关系的安装

    
    
    $ sudo apt-get -f install
    
    
    

    没有任何错误,这样我们就安装成功了,然后你可以运行emacs程序

    查看已安装软件包的安装目录

    如果你依然在纠结到底linux将软件安装到了什么地方,那么很幸运你将可以通过dpkg找到答案

    使用dpkg -L查看deb包目录信息

    $ sudo dpkg -L emacs








    
    


     
     
     
     
     
     
     
     
    
    
    
    
     



     

  • 相关阅读:
    Django-用户认证组件
    Django-session组件
    Axer-使用Msfvenom自动创建有效负载的工具
    CVE-2020-0668-Windows服务跟踪中的普通特权升级错误
    隐藏Web Shell
    404 not found Webshell
    渗透测试流程
    IIS inprocess
    分布式.Net
    WPF UnhandledException
  • 原文地址:https://www.cnblogs.com/baka/p/4823862.html
Copyright © 2020-2023  润新知