走进 Linux shell (一)

1. GNU/Linux shell


GNU/Linux shell是一种特殊的交互式工具。它为用户提供了启动程序,管理文件系统的文件,以及管理运行在 Linux 系统上的进程的途径。shell 的核心
是命令行提示符。命令行提示符是 shell 负责交互的部分,它允许输入文本命令,然后解释命令,并在内核中执行。

shell 包含了一组内部命令,用这些命令可以完成诸如复制文件,移动文件,重命名文件,显示和终止系统中正在运行的程序等操作。shell 也允许在命令行
提示符中输入程序的名称,它会将程序名传递给内核以启动它。

也可以将多个 shell 命令放入文件中作为程序执行,这些文件被称作 shell 脚本。在命令行上执行的任何命令都可以放进一个 shell 脚本中作为一组命令
的一部分执行,这为创建那种需要把几个命令放在一起的来工作的工具提供了便利。

在 Linux 系统中,通常有好几种 Linux shell 可用。不同的 shell 有不同的特性,有些更利于创建脚本,有些则更利于管理进程。所有 Linux 发行版默认
的 shell 都是 bash shell. bash shell 由 GNU 项目开发,被当做标准的 Unix shell —— Bourne shell(以创建者的名字命名)的替代品。

除了 bash shell, 还有其它几种常见的 shell, 下表列出 Linux 中常见的几种 shell

        Linux shell
        +-------+---------------------------------------------------------------------------------------------------+
        | shell    |    描 述                                                                                            |
        +-------+---------------------------------------------------------------------------------------------------+
        | ash    | 一种运行在内存受限环境中简单的轻量级shell,但与bash shell完全兼容                                    |
        +-------+---------------------------------------------------------------------------------------------------+
        | korn    | 一种与Bourne shell兼容的编程shell,但支持如关联数组和浮点运算等一些高级的编程特性                    |
        +-------+---------------------------------------------------------------------------------------------------+
        | tcsh    | 一种将C语言中的一些元素引入到shell脚本中的shell                                                    |
        +-------+---------------------------------------------------------------------------------------------------+
        | zsh    | 一种结合了bash、tcsh和korn的特性,同时提供高级编程特性、共享历史文件和主题化提示符的高级 shell    |
        +-------+---------------------------------------------------------------------------------------------------+

2. 进入命令行
-----------------------------------------------------------------------------------------------------------------------------------------
由shell所提供的文本命令行界面(command line interface, CLI), 只能接受文本输入,也只能显示出文本和基本的图形输出。

2.1 控制台终端
-----------------------------------------------------------------------------------------------------------------------------------------
进入 CLI 的一种方法时让 Linux 系统退出图形化桌面模式,进入文本模式。这样在显示器上就只有一个简单的 shell CLI, 跟图形化桌面出现以前一样,这
种模式成为 Linux 控制台,它仿真了早期的硬接线控制台终端,而且是一种同 Linux 系统交互的直接接口。

Linux 系统启动后,它会自动创建一些虚拟控制台。虚拟控制台是运行在 Linux 系统内存中的终端会话。不需要在计算机上连接多个哑终端,大多数 Linux
发行版都会启动 5~6 个(可能更多)的虚拟控制台,在计算机键盘上就可以访问它们,按键 Ctrl + Alt + F1~F7。

2.2 图形化终端
-----------------------------------------------------------------------------------------------------------------------------------------
除了虚拟化终端控制台,还可以使用Linux图形化桌面环境中的终端仿真包。终端仿真包会在一个桌面图形化窗口中模拟控制台终端的使用。相较于虚拟化
控制台终端,图形化桌面环境提供了更多访问 CLI 的方式。在图形化环境下,有大量可用的图形化终端仿真器。每个软件包都有各自独特的特性和选项。其
中常用的软件包有:GNOME Terminal, Konsole Terminal 和 xterm。


    ■ 使用GNOME Terminal 仿真器
    -------------------------------------------------------------------------------------------------------------------------------------
    GNOME Terminal 是 GNOME 桌面环境的默认终端仿真器。很多发行版,如 RHEL、Fedora 和 CentOS,默认采用的都是 GNOME 桌面环境,因此 GNOME
    Terminal 自然也就是默认配备。不过其他一些桌面环境,比如 Ubuntu Unity,也采用 GNOME Terminal 作为默认的终端仿真软件包。

    在GNOME桌面环境中,找到左上角的菜单,点击 Applications,从下拉菜单中选择System Tools,点击 Terminal。写成简写法的话,这一系列操作就像
    这样:Applications > System Tools > Terminal。

    在 Unity 桌面环境中,Dash > Search,然后输入 Terminal。GNOME 终端会作为一个名为 Terminal 的应用程序显示在Dash区域。点击对应的图标就可
    以打开 GNOME 终端仿真器。


    ■ 使用Konsole Terminal 仿真器
    -------------------------------------------------------------------------------------------------------------------------------------
    Konsole Terminal 是 KDE 桌面环境的默认终端仿真器,必须通过菜单才能访问。找到屏幕左下角名为 Kickoff Application Launcher 的图标,然后
    依次点击 Applications > System > Terminal (Konsole)。


    ■ 使用xterm 终端仿真器
    -------------------------------------------------------------------------------------------------------------------------------------
    最古老也是最基础的终端仿真软件包是xterm。xterm软件包在X Window出现之前就有了,通常默认包含在发行版中。尽管xterm是功能完善的仿真软件包,
    但是它并不需要太多的资源(如内存)来运行。正因为如此,在专门为老旧硬件设计的 Linux 发行版中,xterm非 常流行。有些图形化桌面环境就用它
    作为默认终端仿真器软件包。

    在 Ubuntu 的 Unity桌面中,xterm 是默认安装的。可以通过 Dash > Search,然后输入 xterm 进行访问。xterm 会作为一个名为 XTerm 的应用出现在
    Dash 区域。点击对应的图标就可以打开 xterm 终端仿真器。

    GNOME 和 KDE 桌面环境中并没有默认安装 xterm。得先安装它。安装完成之后,必须从另一个终端仿真器中启动xterm。打开一个终端仿真器进入CLI,
    输入 xterm 并按回车键。

    
3. 基本的 bash shell 命令
-----------------------------------------------------------------------------------------------------------------------------------------
GNU bash shell 能提供对 Linux 系统的交互式访问,它是作为普通程序运行的,通常是在用户登录终端时启动。登录时系统启动的 shell 依赖于用户账号
的配置。

/etc/passwd 文件包含了所有系统用户账户列表以及每个用户的基本配置信息,其中包括账户登录时所使用的 shell:

    devalone:x:1000:1000:MichaelY.:/home/devalone:/bin/bash

此文件的每一个条目为一行,有七个字段,字段之间用冒号分隔,其中最后一个字段指定了用户使用的 shell 程序。

尽管 bash shell 会在登录时自动启动,但是否会出现 shell 命令行界面则依赖于所使用的登录方式。如果采用虚拟控制台登录, CLI 提示符会自动出现,
可以输入 shell 命令,但如果通过图形化桌面环境登录 Linux 系统,就需要启动一个图形化终端仿真器来访问 shell CLI 提示符。

3.1 遍历目录
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 将文件存储在单个目录结构中,这个目录被称为虚拟目录 (virtual directory)。虚拟目录将安装在 PC 上的所有存储设备的文件路径纳入单个目录
结构中。Linux 虚拟目录结构只包含一个称为根 (root) 目录的基础目录。根目录下的目录和文件会按照访问它们的目录路径一一列出。

在 Linux 文件系统上,可以使用切换目录命令 cd 将 shell 会话切换到另一目录。

格式:
    cd destination
    
cd 命令可接受单个参数 destination, 用以指定想切换到的目录名。如果没有为 cd 命令指定目标路径,它将切换到用户主目录。

destination 参数可以用两种方式表示:一种是使用绝对文件路径,另一种是使用相对文件路径。


    ● 绝对文件路径
    -------------------------------------------------------------------------------------------------------------------------------------
    用户可在虚拟目录中采用绝对文件路径引用目录名。绝对文件路径定义了在虚拟目录结构中该目录的确切位置,以虚拟目录的根目录开始,相当于目录的
    全名。绝对文件路径总是以正斜线(/)作为起始,指明虚拟文件系统的根目录。因此,如果要指向 usr 目录所包含的 bin 目录下的用户二进制文件,可
    以使用如下绝对文件路径:

        /usr/bin
        
    使用绝对文件路径可以清晰表明用户想切换到的确切位置。要用绝对文件路径来切换到文件系统中的某个特定位置,只需在 cd 命令后指定全路径名:
    
        [devalone@devalone ~]$ cd /usr/bin
        [devalone@devalone bin]$
        
    波浪号(~) 表明 shell 会话位于用户的主目录中。
    
    pwd 命令可以显示出 shell 会话的当前目录,这个目录被称为当前工作目录。
    
        [devalone@devalone bin]$ pwd
        /usr/bin
    
    
    ● 相对文件路径
    -------------------------------------------------------------------------------------------------------------------------------------
    相对文件路径允许用户指定一个基于当前位置的目标文件路径。相对文件路径不以代表根目录的正斜线 (/) 开头,而是以目录名或是一个特殊的字符
    开始。例如当前位于 home 目录,想切换到 devel 子目录,可以使用 cd 命令加上一个相对文件路径:
        [devalone@devalone ~]$ pwd
        /home/devalone

        [devalone@devalone ~]$ cd devel
        [devalone@devalone devel]$ pwd
        /home/devalone/devel

    可以在任何包含子目录的目录中使用带有相对文件路径的 cd 命令。也可以使用一个特殊字符来表示相对目录位置。

    有两个特殊字符可用于相对文件路径中:
        □ 单点符(.),表示当前目录;
        □ 双点符(..),表示当前目录的父目录。
    可以使用单点符,但对于 cd 命令来说没什么意义。双点符在目录层级中移动时非常便利。如:
    
        [devalone@devalone devel]$ pwd
        /home/devalone/devel
        [devalone@devalone devel]$ cd ../repo
        [devalone@devalone repo]$

    

3.2 文件和目录列表
-----------------------------------------------------------------------------------------------------------------------------------------
要想知道系统中有哪些文件,可以使用列表命令(ls)。


ls命令最基本的形式会显示当前目录下的文件和目录:

    [devalone@devalone study]$ ls
    junit-4.11-javadoc  junit-4.11-javadoc.jar  junit-in-action-II  shell-script

可用带 -F 参数的 ls 命令轻松区分文件和目录

    junit-4.11-javadoc/  junit-4.11-javadoc.jar  junit-in-action-II/  shell-script/

-F 参数在目录名后加了正斜线 (/),以方便用户在输出中分辨它们。类似地,它会在可执行文件(比如上面的my_script文件) 的后面加个星号,以便用户找出
可在系统上运行的文件。

要把隐藏文件和普通文件及目录一起显示出来,要用到 -a 参数。

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

    [devalone@devalone shell-script]$ ls -l
    总用量 96
    drwxrwxr-x. 2 devalone devalone 4096 1月   2 12:16 12
    drwxrwxr-x. 2 devalone devalone 4096 1月   2 17:17 13
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 13:15 14
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 13:15 15
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 13:15 16
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 13:15 17
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 13:15 18
    drwxrwxr-x. 2 devalone devalone 4096 1月   7 16:06 19
    drwxrwxr-x. 2 devalone devalone 4096 1月  15 13:53 20
    drwxrwxr-x. 2 devalone devalone 4096 1月  15 13:53 21
    drwxrwxr-x. 2 devalone devalone 4096 1月  15 13:53 22
    drwxrwxr-x. 2 devalone devalone 4096 1月  15 13:53 23
    drwxrwxr-x. 2 devalone devalone 4096 1月  15 14:40 24
    -rwxrwxr-x. 1 devalone devalone  104 1月   2 11:32 test10.sh
    -rwxrwxr-x. 1 devalone devalone  150 1月   2 11:32 test11.sh
    -rwxrwxr-x. 1 devalone devalone  177 1月   2 11:32 test12.sh
    -rwxrwxr-x. 1 devalone devalone  109 1月   2 11:32 test13.sh
    -rwxrwxr-x. 1 devalone devalone  152 1月   2 11:32 test1.sh
    -rwxrwxr-x. 1 devalone devalone  123 1月   2 11:32 test2.sh
    -rwxrwxr-x. 1 devalone devalone  159 1月   2 11:32 test3.sh
    -rwxrwxr-x. 1 devalone devalone  123 1月   2 11:32 test4.sh
    -rwxrwxr-x. 1 devalone devalone   68 1月   2 11:32 test5.sh
    -rwxrwxr-x. 1 devalone devalone   73 1月   2 11:32 test9.sh
    -rw-rw-r--. 1 devalone devalone   72 1月   7 13:15 testfile


    
    ● 过滤输出列表
    -------------------------------------------------------------------------------------------------------------------------------------
    ls 命令支持在命令行中定义过滤器,它会用过滤器来决定应该在输出中显示哪些文件或目录。这个过滤器就是一个进行简单的文本匹配的字符串。可以
    用在命令行参数之后:
    
        [devalone@devalone shell-script]$ ls -l test9.sh
        -rwxrwxr-x. 1 devalone devalone 73 1月   2 11:32 test9.sh

    当指定特定文件的名称作为过滤器时, ls 命令只会显示该文件的信息。有时可能不知道要找的那个文件的确切名称,可以使用通配符匹配过滤。 ls
    命令能够识别标准通配符,并在过滤器中用它们进行模式匹配:
    
        □ 问号(?)代表一个字符;
         □ 星号(*)代表零个或多个字符。

    示例:
        [devalone@devalone shell-script]$ ls -l test1?.sh
        -rwxrwxr-x. 1 devalone devalone 104 1月   2 11:32 test10.sh
        -rwxrwxr-x. 1 devalone devalone 150 1月   2 11:32 test11.sh
        -rwxrwxr-x. 1 devalone devalone 177 1月   2 11:32 test12.sh
        -rwxrwxr-x. 1 devalone devalone 109 1月   2 11:32 test13.sh

        [devalone@devalone shell-script]$ ls -l test*.sh
        -rwxrwxr-x. 1 devalone devalone 104 1月   2 11:32 test10.sh
        -rwxrwxr-x. 1 devalone devalone 150 1月   2 11:32 test11.sh
        -rwxrwxr-x. 1 devalone devalone 177 1月   2 11:32 test12.sh
        -rwxrwxr-x. 1 devalone devalone 109 1月   2 11:32 test13.sh
        -rwxrwxr-x. 1 devalone devalone 152 1月   2 11:32 test1.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test2.sh
        -rwxrwxr-x. 1 devalone devalone 159 1月   2 11:32 test3.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test4.sh
        -rwxrwxr-x. 1 devalone devalone  68 1月   2 11:32 test5.sh
        -rwxrwxr-x. 1 devalone devalone  73 1月   2 11:32 test9.sh

    在过滤器中使用星号和问号被称为文件扩展匹配((file globbing), 指的是使用通配符进行模式匹配的过程。通配符正式的名称为元字符通配符
    (metacharacter wildcards)。除了星号和问号之外,还有更多的元字符通配符可用于文件扩展匹配,可以使用中括号。

        [devalone@devalone shell-script]$ ls -l test[12].sh
        -rwxrwxr-x. 1 devalone devalone 152 1月   2 11:32 test1.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test2.sh
    
    也可以指定字符范围,如 [1-3]:
        
        [devalone@devalone shell-script]$ ls -l test[1-3].sh
        -rwxrwxr-x. 1 devalone devalone 152 1月   2 11:32 test1.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test2.sh
        -rwxrwxr-x. 1 devalone devalone 159 1月   2 11:32 test3.sh

    可以使用感叹号(!) 将不需要的内容排除:

        [devalone@devalone shell-script]$ ls -l test[!3].sh
        -rwxrwxr-x. 1 devalone devalone 152 1月   2 11:32 test1.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test2.sh
        -rwxrwxr-x. 1 devalone devalone 123 1月   2 11:32 test4.sh
        -rwxrwxr-x. 1 devalone devalone  68 1月   2 11:32 test5.sh
        -rwxrwxr-x. 1 devalone devalone  73 1月   2 11:32 test9.sh


3.3 处理文件
-----------------------------------------------------------------------------------------------------------------------------------------

3.3.1 创建文件
-----------------------------------------------------------------------------------------------------------------------------------------
可以使用 touch 命令创建空文件:

    [devalone@devalone shell-script]$ touch test
    [devalone@devalone shell-script]$ ls -l test
    -rw-rw-r--. 1 devalone devalone 0 7月   2 19:09 test

touch命令还可用来改变文件的修改时间。这个操作并不需要改变文件的内容。
    
    [devalone@devalone shell-script]$ ls -l test
    -rw-rw-r--. 1 devalone devalone 0 7月   2 19:09 test
    [devalone@devalone shell-script]$ touch test
    [devalone@devalone shell-script]$ ls -l test
    -rw-rw-r--. 1 devalone devalone 0 7月   2 19:10 test

3.3.2 复制文件
-----------------------------------------------------------------------------------------------------------------------------------------
cp 命令,在文件系统中将文件和目录从一个位置复制到另一个位置。
基本用法:

    cp source destination

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

    [devalone@devalone shell-script]$ cp test test2
    [devalone@devalone shell-script]$ ls -l test
    -rw-rw-r--. 1 devalone devalone 0 7月   2 19:10 test
    [devalone@devalone shell-script]$ ls -l test2
    -rw-rw-r--. 1 devalone devalone 0 7月   2 19:15 test2

如果目标文件已经存在,cp 命令可能并不会提醒这一点。最好是加上 -i 选项,强制 shell 询问是否需要覆盖已有文件。

    [devalone@devalone shell-script]$ cp -i test test2
    cp:是否覆盖'test2'? n

前面介绍了特殊符号可以用在相对文件路径中。其中的单点符(.) 就很适合用于 cp 命令。记住,单点符表示当前工作目录。

    [devalone@devalone shell-script]$ cp -i /etc/sysconfig/network .
    [devalone@devalone shell-script]$ ls -l network
    -rw-rw-r--. 1 devalone devalone 22 7月   2 19:21 network

cp命令的 -R 参数威力强大。可以用它在一条命令中递归地复制整个目录的内容。

    [devalone@devalone shell-script]$ cp -R 12 12-test

在执行 cp –R 命令之前,目录 12-test 并不存在。它是随着 cp –R 命令被创建的,整个 12 目录中的内容都被复制到其中。

也可以在cp命令中使用通配符:

    [devalone@devalone shell-script]$ mkdir dirsh
    [devalone@devalone shell-script]$ cp test?.sh dirsh/
    [devalone@devalone shell-script]$ ll dirsh
    总用量 24
    -rwxrwxr-x. 1 devalone devalone 152 7月   2 19:32 test1.sh
    -rwxrwxr-x. 1 devalone devalone 123 7月   2 19:32 test2.sh
    -rwxrwxr-x. 1 devalone devalone 159 7月   2 19:32 test3.sh
    -rwxrwxr-x. 1 devalone devalone 123 7月   2 19:32 test4.sh
    -rwxrwxr-x. 1 devalone devalone  68 7月   2 19:32 test5.sh
    -rwxrwxr-x. 1 devalone devalone  73 7月   2 19:32 test9.sh
    

3.3.3 制表键(tab)自动补全
-----------------------------------------------------------------------------------------------------------------------------------------
制表键(tab)自动补全功能允许在输入文件名或目录名时按一下制表键,让 shell 将内容补充完整。

    [devalone@devalone shell-script]$ cp network-functions ff

上面例子输入 cp net,然后按下 [tab] 键,shell 将整个文件名剩下的部分自动补全。当然目标还是要自己输入的。


3.3.4 链接文件
-----------------------------------------------------------------------------------------------------------------------------------------
链接是目录中指向文件真实位置的占位符。在 Linux 中有两种不同类型的文件链接:

    □ 符号链接
    □ 硬链接
    
符号链接就是一个实实在在的文件,它指向存放在虚拟目录结构中某个地方的另一个文件。这两个通过符号链接在一起的文件,彼此内容并不相同。

要创建一个符号链接,原始文件必须事先存在。然后使用 ln 命令及 -s 选项创建:

    [devalone@devalone shell-script]$ ln -s testfile testfile_s1
    [devalone@devalone shell-script]$ ls -l testfile*
    -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile
    lrwxrwxrwx. 1 devalone devalone  8 7月   2 19:51 testfile_s1 -> testfile
    [devalone@devalone shell-script]$

注意符号链接的名字 testfile_s1 位于 ln 命令中的第二个参数位置上。显示在长列表中符号文件名后的->符号表明该文件是链接到文件 testfile 上的
一个符号链接。

另外还要注意的是,符号链接的文件大小与数据文件的文件大小。符号链接 testfile_s1 只有 8 个字节,而 testfile 有 72 个字节。这是因为
testfile_s1 仅仅只是指向 testfile 而已。它们的内容并不相同,是两个完全不同的文件。

硬链接会创建独立的虚拟文件,其中包含了原始文件的信息及位置。但是它们从根本上而言是同一个文件。引用硬链接文件等同于引用了源文件。要创建硬链接
原始文件也必须事先存在,只不过这次使用 ln 命令时不再需要加入额外的参数。

    [devalone@devalone shell-script]$ ln test9.sh test9.sh_h1
    [devalone@devalone shell-script]$ ls -li test9.sh*
    1977755 -rwxrwxr-x. 2 devalone devalone 73 1月   2 11:32 test9.sh
    1977755 -rwxrwxr-x. 2 devalone devalone 73 1月   2 11:32 test9.sh_h1

在上面的例子中,我们使用 ls -li 命令显示了 test9.sh* 的 inode 编号以及长列表。注意,带有硬链接的文件共用 inode 编号。这是因为它们终归是
同一个文件。还要注意的是,链接计数(列表中第三项) 显示这两个文件都有两个链接。另外,它们的文件大小也一模一样。

    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    只能对处于同一存储媒体的文件创建硬链接。要想在不同存储媒体的文件之间创建链接,只能使用符号链接。
    


3.3.5 重命名文件
-----------------------------------------------------------------------------------------------------------------------------------------
在Linux中,重命名文件称为移动(moving)。mv命令可以将文件和目录移动到另一个位置或重新命名。

    [devalone@devalone shell-script]$ ll -i testfile*
    1973525 -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfile
    1977761 -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile2

    [devalone@devalone shell-script]$ mv testfile testfilezz

    [devalone@devalone shell-script]$ ls -li testfile*
    1977761 -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile2
    1973525 -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfilezz


注意,移动文件会将文件名从 testfile 更改为 testfilezz,但 inode 编号和时间戳保持不变。这是因为 mv 只影响文件名。

也可以使用mv来移动文件的位置:

    [devalone@devalone shell-script]$ mv testfilezz ~/devel/
    [devalone@devalone shell-script]$ ls -li testfile*
    1977761 -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile2

    [devalone@devalone shell-script]$ ls -li ~/devel/testfile*
    1973525 -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 /home/devalone/devel/testfilezz

也可以使用mv命令移动文件位置并修改文件名称,这些操作只需一步就能完成:

    [devalone@devalone shell-script]$ mv ~/devel/testfilezz ./testfile
    [devalone@devalone shell-script]$ ls -li testfile*
    1973525 -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfile
    1977761 -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile2

也可以使用mv命令移动整个目录及其内容:
    [devalone@devalone shell-script]$ ls -ld network-scripts
    drwxr-xr-x. 2 devalone devalone 4096 7月   2 19:26 network-scripts

    [devalone@devalone shell-script]$ mv network-scripts  network-scripts-zz
    [devalone@devalone shell-script]$ ls -ld network-scripts*
    drwxr-xr-x. 2 devalone devalone 4096 7月   2 19:26 network-scripts-zz
    
    
3.3.6 删除文件
-----------------------------------------------------------------------------------------------------------------------------------------
在 Linux 中,删除(deleting)叫作移除(removing)。bash shell中删除文件的命令是 rm。rm 命令的基本格式非常简单:

    [devalone@devalone shell-script]$ ls -l testfile*
    -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfile
    -rw-rw-r--. 1 devalone devalone 72 1月   7 13:15 testfile2

    [devalone@devalone shell-script]$ rm -i testfile2
    rm:是否删除普通文件 'testfile2'?y
    [devalone@devalone shell-script]$ ls -l testfile*
    -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfile

注意,-i 命令参数提示是不是要真的删除该文件。bash shell 中没有回收站或垃圾箱,文件一旦删除,就无法再找回。因此,在使用 rm 命令时,要养成
总是加入 -i 参数的好习惯。

也可以使用通配符删除成组的文件:

    [devalone@devalone shell-script]$ ls -l testfile*
    -rw-rw-r--. 1 devalone devalone 72 7月   2 20:08 testfile
    -rw-rw-r--. 1 devalone devalone 72 7月   2 20:24 testfile-zz
    [devalone@devalone shell-script]$ rm -i testfile*
    rm:是否删除普通文件 'testfile'?n
    rm:是否删除普通文件 'testfile-zz'?

rm 命令的另外一个特性是,如果要删除很多文件且不受提示符的打扰,可以用 -f 参数强制删除。千万小心!

3.4 处理目录
-----------------------------------------------------------------------------------------------------------------------------------------
在Linux中,有些命令(比如cp命令)对文件和目录都有效,而有些只对目录有效。


3.4.1 创建目录
-----------------------------------------------------------------------------------------------------------------------------------------
使用 mkdir 命令:

    [devalone@devalone shell_test]$ mkdir dir
    [devalone@devalone shell_test]$ ll
    总用量 4
    drwxrwxr-x. 2 devalone devalone 4096 7月   3 10:18 new_dir

要想同时创建多个目录和子目录,需要加入 -p 参数:

    [devalone@devalone shell_test]$ mkdir -p new_dir/sub_dir/under_dir
    [devalone@devalone shell_test]$ ls -R
    .:
    new_dir

    ./new_dir:
    sub_dir

    ./new_dir/sub_dir:
    under_dir

    ./new_dir/sub_dir/under_dir:

3.4.2 删除目录
-----------------------------------------------------------------------------------------------------------------------------------------
删除目录的基本命令是 rmdir,默认情况下,rmdir 命令只删除空目录。

    [devalone@devalone shell_test]$ rmdir new_dir/sub_dir/under_dir/
    [devalone@devalone shell_test]$ ls -R
    .:
    new_dir

    ./new_dir:
    sub_dir

    ./new_dir/sub_dir:


也可以在整个非空目录上使用rm命令。使用 -r 选项使得命令可以向下进入目录,删除其中的文件,然后再删除目录本身。一次性删除目录及其所有内容的
终极大法就是使用带有 -r 参数和 -f 参数的 rm 命令。

    [devalone@devalone shell_test]$ touch new_dir/new_file
    [devalone@devalone shell_test]$ ls -R
    .:
    new_dir

    ./new_dir:
    new_file  sub_dir

    ./new_dir/sub_dir:
    [devalone@devalone shell_test]$ rm -rf new_dir
    [devalone@devalone shell_test]$ ll
    总用量 0

    
    
3.5 查看文件内容
-----------------------------------------------------------------------------------------------------------------------------------------


3.5.1 查看文件类型
-----------------------------------------------------------------------------------------------------------------------------------------
file 命令是一个便捷工具。它能够探测文件的内部,并决定文件是什么类型的:

    [devalone@devalone shell_test]$ file testfile
    testfile: ASCII text

测试目录:
    [devalone@devalone shell_test]$ file new_dir
    new_dir: directory

测试链接:
    [devalone@devalone shell_test]$ ln -s testfile ln_test    
    [devalone@devalone shell_test]$ file ln_test
    ln_test: symbolic link to testfile

测试脚本文件:
    [devalone@devalone shell_test]$ file test1.sh
    test1.sh: Bourne-Again shell script, ASCII text executable

测试二进制可执行文件:

    [devalone@devalone shell_test]$ file /bin/ls
    /bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
    for GNU/Linux 2.6.32, BuildID[sha1]=0ac5c509289d650534ce80cdbf5b72744b5c5f3d, stripped

    
    
3.5.2 查看整个文件
-----------------------------------------------------------------------------------------------------------------------------------------


    cat 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    [devalone@devalone shell_test]$ cat testfile
    This is the first line.
    This is the second line.
    This is the third line.

    
    -n 参数会给所有的行加上行号:
    [devalone@devalone shell_test]$ cat -n testfile
     1  This is the first line.
     2  This is the second line.
     3  This is the third line.
     4

    如果只想给有文本的行加上行号,可以用 -b 参数,在检查脚本时很有用:
    
     [devalone@devalone shell_test]$ cat -b test1.sh
     1  #!/bin/bash
     2  # This script displays the date and who's log on
     3  echo -n  "The time and date are: "
     4  date
     5  echo "Let's see who's logged into the system:"
     6  who

    如果不想让制表符出现,可以用 -T 参数:-T 参数会用 ^I 字符组合去替换文中的所有制表符:
    [devalone@devalone shell_test]$ cat -T testfile
    This is the first line.
    This is the second line.
    This is the thir^Id line.

    
    
    more 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    more 命令会显示文本文件的内容,但会在显示每页数据之后停下来:
    
        [devalone@devalone shell_test]$ more /etc/passwd
    
    more命令是分页工具。浏览完之后,按 q 键退出。more命令只支持文本文件中的基本移动。如果要更多高级功能,可以试试 less 命令。
    
    
    less 命令
    -------------------------------------------------------------------------------------------------------------------------------------    
    less 命令实为 more 命令的升级版。它提供了一些极为实用的特性,能够实现在文本文件中前后翻动,而且还有一些高级搜索功能。
    
    less命令的操作和more命令基本一样,一次显示一屏的文件文本。除了支持和 more 命令相同的命令集,它还包括更多的选项。
    
    可以输入 man less 浏览对应的手册页。man 工具本身就是搭载 less 命令进行操作的。
    
    
    
3.5.3 查看部分文件
-----------------------------------------------------------------------------------------------------------------------------------------    
通常要查看的数据要么在文本文件的开头,要么在文本文件的末尾。如果这些数据是在大型文件的起始部分,那就得等 cat 或 more 加载完整个文件
之后才能看到。如果数据是在文件的末尾(比如日志文件),那可能需要翻过成千上万行的文本才能到最后的内容。


    tail 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    tail命令会显示文件最后几行的内容(文件的“尾部”)。默认情况下,它会显示文件的末尾10行。可以向tail命令中加入 -n 参数来修改所显示的行数:
    
    [devalone@devalone shell_test]$ cat testfile
    This is the first line.
    This is the second line.
    This is the third line.
    This is the fourth line.

    [devalone@devalone shell_test]$ tail testfile
    This is the first line.
    This is the second line.
    This is the third line.
    This is the fourth line.

    [devalone@devalone shell_test]$ tail -n 2 testfile
    This is the third line.
    This is the fourth line.

    也可以将 -n 2 参数直接写成 -2 形式:
    [devalone@devalone shell_test]$ tail -2 testfile
    This is the third line.
    This is the fourth line.

    
    head 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    会显示文件开头那些行的内容。默认情况下,它会显示文件前10行的文本:

    [devalone@devalone shell_test]$ head testfile
    This is the first line.
    This is the second line.
    This is the third line.
    This is the fourth line.
    This is the 5th line.
    This is the 6th line.
    This is the 7th line.
    This is the 8th line.
    This is the 9th line.
    This is the 10th line.

    类似于 tail 命令,它也支持 -n 参数,这样就可以指定想要显示的内容了。这两个命令都允许在 "-" 后面输入想要显示的行数:

    [devalone@devalone shell_test]$ head -5 testfile
    This is the first line.
    This is the second line.
    This is the third line.
    This is the fourth line.
    This is the 5th line.

4. 更多的 bash shell 命令
-----------------------------------------------------------------------------------------------------------------------------------------

4.1 监测程序
-----------------------------------------------------------------------------------------------------------------------------------------

4.1.1 探查进程
-----------------------------------------------------------------------------------------------------------------------------------------
当程序运行在系统上时,称之为进程(process)。要检测这些进程,需要熟悉 ps 命令的用法,ps 命令好比工具中的瑞士军刀,它能输出运行在系统上的所有
程序的许多信息。随着功能的强大而来的是其复杂性,ps 有数不清的参数,这或许是让它成为最难掌握的命令。大多数系统管理员在掌握了能提供需要的一组
参数之后,就一直坚持只使用这组参数。

默认情况下, ps 并不会提供全部的信息:只会显示运行在当前控制台下的属于当前用户的进程

[devalone@devalone shell_test]$ ps
  PID TTY          TIME CMD
 2373 pts/1    00:00:00 bash
 3108 pts/1    00:00:00 ps


Linux系统中使用的GNU ps命令支持3种不同类型的命令行参数:
    □ Unix风格的参数,前面加单连字符 "-";
    □ BSD风格的参数,前面不加连字符 "-";
    □ GNU风格的长参数,前面加双连字符 "--"

以 Unix 风格的参数为例说明:Unix 风格的参数是从贝尔实验室开发的 AT&T Unix 系统上原有的 ps 命令继承下来的。参数如下表所示:

    Unix风格的ps命令参数
    +---------------+-----------------------------------------------------------------------------------------
    | 参 数            |    描 述
    +---------------+-----------------------------------------------------------------------------------------
    | -A            | 显示所有进程
    +---------------+-----------------------------------------------------------------------------------------
    | -N            | 显示与指定参数不符的所有进程
    +---------------+-----------------------------------------------------------------------------------------
    | -a            | 显示除控制进程(session leader①)和无终端进程外的所有进程
    +---------------+-----------------------------------------------------------------------------------------
    | -d            | 显示除控制进程外的所有进程
    +---------------+-----------------------------------------------------------------------------------------
    | -e            | 显示所有进程
    +---------------+-----------------------------------------------------------------------------------------
    | -C cmdlist    | 显示包含在cmdlist列表中的进
    +---------------+-----------------------------------------------------------------------------------------
    | -G grplist    | 显示组ID在grplist列表中的进程
    +---------------+-----------------------------------------------------------------------------------------
    | -U userlist    | 显示属主的用户ID在userlist列表中的进程
    +---------------+-----------------------------------------------------------------------------------------
    | -g grplist    | 显示会话或组ID在grplist列表中的进程
    +---------------+-----------------------------------------------------------------------------------------
    | -p pidlist    | 显示PID在pidlist列表中的进程
    +---------------+-----------------------------------------------------------------------------------------
    | -s sesslist    | 显示会话ID在sesslist列表中的进程
    +---------------+-----------------------------------------------------------------------------------------
    | -t ttylist    | 显示终端ID在ttylist列表中的进程
    +---------------+-----------------------------------------------------------------------------------------
    | -u userlist    | 显示有效用户ID在userlist列表中的进程
    +---------------+-----------------------------------------------------------------------------------------
    | -F            | 显示更多额外输出(相对-f参数而言)
    +---------------+-----------------------------------------------------------------------------------------
    | -O format        | 显示默认的输出列以及format列表指定的特定列
    +---------------+-----------------------------------------------------------------------------------------
    | -M            | 显示进程的安全信息
    +---------------+-----------------------------------------------------------------------------------------
    | -c            | 显示进程的额外调度器信息
    +---------------+-----------------------------------------------------------------------------------------
    | -f            | 显示完整格式的输出
    +---------------+-----------------------------------------------------------------------------------------
    | -j            | 显示任务信息
    +---------------+-----------------------------------------------------------------------------------------
    | -l            | 显示长列表
    +---------------+-----------------------------------------------------------------------------------------
    | -o format        | 仅显示由format指定的列
    +---------------+-----------------------------------------------------------------------------------------
    | -y            | 不要显示进程标记(process flag,表明进程状态的标记)
    +---------------+-----------------------------------------------------------------------------------------
    | -Z            | 显示安全标签(security context)信息
    +---------------+-----------------------------------------------------------------------------------------
    | -H            | 用层级格式来显示进程(树状,用来显示父进程)
    +---------------+-----------------------------------------------------------------------------------------
    | -n namelist    | 定义了WCHAN列显示的值
    +---------------+-----------------------------------------------------------------------------------------
    | -w            | 采用宽输出模式,不限宽度显示
    +---------------+-----------------------------------------------------------------------------------------
    | -L            | 显示进程中的线程
    +---------------+-----------------------------------------------------------------------------------------
    | -V            | 显示 ps 命令的版本号
    +---------------+-----------------------------------------------------------------------------------------

还有很多... 更多内容查看 man ps

要查看系统上运行的所有进程,可用 -ef 参数组合:

    [devalone@devalone shell_test]$ ps -ef
    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 10:12 ?        00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 23
    root         2     0  0 10:12 ?        00:00:00 [kthreadd]
    root         4     2  0 10:12 ?        00:00:00 [kworker/0:0H]
    root         6     2  0 10:12 ?        00:00:00 [mm_percpu_wq]
    root         7     2  0 10:12 ?        00:00:00 [ksoftirqd/0]
    root         8     2  0 10:12 ?        00:00:00 [rcu_sched]
    root         9     2  0 10:12 ?        00:00:00 [rcu_bh]
    root        10     2  0 10:12 ?        00:00:00 [rcuos/0]
    root        11     2  0 10:12 ?        00:00:00 [rcuob/0]
...


这个例子用了两个参数:-e 参数指定显示所有运行在系统上的进程;-f 参数则扩展了输出,这些扩展的列包含了有用的信息。说明如下:

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

上例中输出了合理数量的信息,这也正是大多数系统管理员希望看到的。如果想要获得更多的信息,可采用 -l 参数,它会产生一个长格式输出:

    [devalone@devalone shell_test]$ ps -l
    F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    0 S  1000  2373  2360  0  80   0 - 30530 wait   pts/1    00:00:00 bash
    0 R  1000  3148  2373  0  80   0 - 36971 -      pts/1    00:00:00 ps

其中:
    F    :内核分配给进程的系统标记。
    S    :进程的状态(O代表正在运行;S代表在休眠;R代表可运行,正等待运行;Z代表僵尸进程,进程已结束但父进程已不存在;T代表停止)。
    PRI    :进程的优先级(越大的数字代表越低的优先级)。
    NI    :谦让度值用来参与决定优先级。
    ADDR:进程的内存地址。
    SZ    :假如进程被换出,所需交换空间的大致大小。
    WCHAN:进程休眠的内核函数的地址。
    

    
4.1.2 实时监测进程
-----------------------------------------------------------------------------------------------------------------------------------------    
ps 命令虽然在收集运行在系统上的进程信息时非常有用,但也有不足之处:它只能显示某个特定时间点的信息。

top 命令跟 ps 命令相似,能够显示进程信息,但它是实时显示的。输出的第一部分显示的是系统的概况:第一行显示了当前时间、系统的运行时间、登录
的用户数以及系统的平均负载。

    [devalone@devalone shell_test]$ top
    top - 12:24:00 up  2:11,  2 users,  load average: 0.00, 0.00, 0.00
    Tasks: 228 total,   1 running, 227 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.1 si,  0.0 st
    KiB Mem :  3921200 total,   597080 free,   781000 used,  2543120 buff/cache
    KiB Swap:  3932156 total,  3932156 free,        0 used.  2571428 avail Mem

      PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
     1889 devalone  20   0 2590496 146404  69768 S   0.7  3.7   0:06.67 gnome-shell
     3177 devalone  20   0  156636   4332   3692 R   0.3  0.1   0:00.13 top
        1 root      20   0  196744   9172   5916 S   0.0  0.2   0:01.30 systemd
        2 root      20   0       0      0      0 S   0.0  0.0   0:00.00 kthreadd
        4 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kworker/0:0H
        6 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 mm_percpu_wq
        7 root      20   0       0      0      0 S   0.0  0.0   0:00.00 ksoftirqd/0
        8 root      20   0       0      0      0 S   0.0  0.0   0:00.68 rcu_sched
        9 root      20   0       0      0      0 S   0.0  0.0   0:00.00 rcu_bh
       10 root      20   0       0      0      0 S   0.0  0.0   0:00.26 rcuos/0
       11 root      20   0       0      0      0 S   0.0  0.0   0:00.00 rcuob/0
       12 root      rt   0       0      0      0 S   0.0  0.0   0:00.00 migration/0
       13 root      rt   0       0      0      0 S   0.0  0.0   0:00.01 watchdog/0

       ...

平均负载有 3 个值:最近 1 分钟的、最近 5 分钟的和最近 15 分钟的平均负载。值越大说明系统的负载越高。由于进程短期的突发性活动,出现最近 1分
钟的高负载值也很常见,但如果近 15 分钟内的平均负载都很高,就说明系统可能有问题。


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    Linux 系统管理的要点在于定义究竟到什么程度才算是高负载。这个值取决于系统的硬件配置以及系统上通常运行的程序。对某个系统来说是高负载的
    值可能对另一系统来说就是正常值。通常,如果系统的负载值超过了2,就说明系统比较繁忙了。


第二行显示了进程概要信息—— 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:进程所对应的命令行名称,也就是启动的程序名。    

默认情况下,top 命令在启动时会按照 %CPU 值对进程排序。可以在 top 运行时使用多种交互命令重新排序。每个交互式命令都是单字符,在 top 命令
运行时键入可改变 top 的行为。键入 f 允许选择对输出进行排序的字段,键入 d 允许修改轮询间隔。键入q可以退出top。

4.1.3 结束进程
-----------------------------------------------------------------------------------------------------------------------------------------
Linux 沿用了 Unix 进行进程间通信的方法。在 Linux 中,进程之间通过信号来通信。进程的信号就是预定义好的一个消息,进程能识别它并决定忽略还是
作出反应。进程如何处理信号是由开发人员通过编程来决定的。大多数编写完善的程序都能接收和处理标准 Unix 进程信号。这些信号定义如下表所示:

查阅信号定义:
    
    man 7 signal

    常见 Linux 进程信号
    +-------+-----------+--------------------------------------------------------------
    | 信 号    | 名 称        | 描 述
    +-------+-----------+--------------------------------------------------------------
    | 1        | SIGHUP     | 挂起
    +-------+-----------+--------------------------------------------------------------
    | 2        | SIGINT    | 中断
    +-------+-----------+--------------------------------------------------------------
    | 3        | SIGQUIT    | 结束运行
    +-------+-----------+--------------------------------------------------------------
    | 4        | SIGILL     | 无效指令
    +-------+-----------+--------------------------------------------------------------
    | 9        | SIGKILL    | 无条件终止
    +-------+-----------+--------------------------------------------------------------
    | 11    | SIGSEGV    | 段错误,非法内存引用
    +-------+-----------+--------------------------------------------------------------
    | 15    | SIGTERM    | 尽可能终止,Termination signal
    +-------+-----------+--------------------------------------------------------------
    | 18    |  SIGCONT    | 在 SIGSTOP 或 TSTP之后恢复执行
    +-------+-----------+--------------------------------------------------------------
    | 19    | SIGSTOP    | 无条件停止运行,但不终止
    +-------+-----------+--------------------------------------------------------------


    ● kill 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    kill 命令可通过进程 ID(PID)给进程发信号。默认情况下,kill命令会向命令行中列出的全部 PID 发送一个 TERM 信号。只能用进程的PID而不能用
    命令名,所以 kill 命令有时并不好用。要发送进程信号,必须是进程的属主或登录为 root 用户。
    
        [devalone@devalone ~]$ kill 3318
        
    SIGTERM 信号告诉进程可能的话就停止运行。不过,如果有不服管教的进程,通常会忽略这个请求。如果要强制终止,-s 参数支持指定其他信号(用
    信号名或信号值)。

        [devalone@devalone ~]$ kill -s 9 3393
    
    或者写成:
    
        [devalone@devalone ~]$ kill -9 3393
    
    
    
    ● killall 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    killall 命令非常强大,它支持通过进程名而不是 PID 来结束进程。killall 命令也支持通配符,这在系统因负载过大而变得很慢时很有用。
    
        [devalone@devalone ~]$ killall -9 top


    
4.2 检测磁盘空间
-----------------------------------------------------------------------------------------------------------------------------------------


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

在图形化桌面环境里,大多数 Linux 发行版都能自动挂载特定类型的可移动存储媒体。可移动存储媒体指的是可从 PC 上轻易移除的媒体,比如 CD-ROM、
软盘和 U盘。


    ● mount 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    默认情况下,mount 命令会输出当前系统上挂载的设备列表。
    
    [devalone@devalone ~]$ mount
    /dev/mapper/fedora_devalone-root on / type ext4 (rw,relatime,seclabel,data=ordered)
    selinuxfs on /sys/fs/selinux type selinuxfs (rw,relatime)
    /dev/mapper/fedora_devalone-home on /home type ext4 (rw,relatime,seclabel,data=ordered)
    /dev/sda1 on /boot type ext4 (rw,relatime,seclabel,data=ordered)
    /dev/mapper/fedora_devalone-var on /var type ext4 (rw,relatime,seclabel,data=ordered)

    ...
    
    mount 命令提供如下四部分信息:
    
    □ 媒体的设备文件名
  □ 媒体挂载到虚拟目录的挂载点
     □ 文件系统类型
     □ 已挂载媒体的访问状态
    
    要手动在虚拟目录中挂载设备,需要以 root 用户身份登录,或是以 root 用户身份运行 sudo 命令。下面是手动挂载媒体设备的基本命令:
    
        mount -t type device directory
        
    type 参数指定了磁盘被格式化的文件系统类型。Linux 可以识别非常多的文件系统类型。如果是和 Windows PC 共用这些存储设备,通常得使用下列
    文件系统类型:
    
    □ vfat:Windows长文件系统。
    □ ntfs:Windows NT、XP、Vista 以及 Windows 7 中广泛使用的高级文件系统。
    □ iso9660:标准CD-ROM文件系统。
    
    
    后面两个参数定义了该存储设备的设备文件的位置以及挂载点在虚拟目录中的位置。如,手动将 U盘 /dev/sdb1 挂载到 /media/disk,可用下面的命令
    
        mount -t vfat /dev/sdb1 /media/disk
    
    -a 参数挂载 /etc/fstab 文件中指定的所有文件系统。
    -o 参数允许在挂载文件系统时添加一些以逗号分隔的额外选项,以下是常用选项:
    
        □ ro:以只读形式挂载。
        □ rw:以读写形式挂载。
        □ user:允许普通用户挂载文件系统。
        □ check=none:挂载文件系统时不进行完整性校验。
        □ loop:挂载一个文件。
    
    
    ● umount 命令
    -------------------------------------------------------------------------------------------------------------------------------------
    从 Linux 系统上移除一个可移动设备时,不能直接从系统上移除,而应该先卸载。
    
    Linux 上不能直接弹出已挂载的 CD。如果在从光驱中移除 CD 时遇到麻烦,通常是因为该 CD 还挂载在虚拟目录里。先卸载它,然后再去尝试弹出。
    
    umount命令的格式:
    
        umount [directory | device ]
    
    umount 命令支持通过设备文件或者是挂载点来指定要卸载的设备。如果有任何程序正在使用设备上的文件,系统就不会允许卸载它:
    

    
4.2.2 使用 df 命令
-----------------------------------------------------------------------------------------------------------------------------------------
有时需要知道在某个设备上还有多少磁盘空间。df 命令可以很方便地查看所有已挂载磁盘的使用情况。

    [devalone@devalone shell_test]$ df
    文件系统                             1K-块      已用      可用 已用% 挂载点
    devtmpfs                           1945972         0   1945972    0% /dev
    tmpfs                              1960600       328   1960272    1% /dev/shm
    tmpfs                              1960600      1600   1959000    1% /run
    tmpfs                              1960600         0   1960600    0% /sys/fs/cgroup
    /dev/mapper/fedora_devalone-root  51475068   8518008  40319236   18% /
    tmpfs                              1960600       116   1960484    1% /tmp
    /dev/mapper/fedora_devalone-home 103081248  47583664  50238320   49% /home
    /dev/sda1                           487652    181444    276512   40% /boot
    /dev/mapper/fedora_devalone-var  321389700 128665696 176375232   43% /var
    tmpfs                               392120        16    392104    1% /run/user/42
    tmpfs                               392120        24    392096    1% /run/user/1000

df 命令有一些命令行参数可用,但基本上不会用到。一个常用的参数是 -h。它会把输出中的磁盘空间按照用户易读的形式显示,通常用 M 来替代兆字节,
用 G 替代吉字节。

    [devalone@devalone shell_test]$ df -h
    文件系统                          容量  已用  可用 已用% 挂载点
    devtmpfs                          1.9G     0  1.9G    0% /dev
    tmpfs                             1.9G  328K  1.9G    1% /dev/shm
    tmpfs                             1.9G  1.6M  1.9G    1% /run
    tmpfs                             1.9G     0  1.9G    0% /sys/fs/cgroup
    /dev/mapper/fedora_devalone-root   50G  8.2G   39G   18% /
    tmpfs                             1.9G  116K  1.9G    1% /tmp
    /dev/mapper/fedora_devalone-home   99G   46G   48G   49% /home
    /dev/sda1                         477M  178M  271M   40% /boot
    /dev/mapper/fedora_devalone-var   307G  123G  169G   43% /var
    tmpfs                             383M   16K  383M    1% /run/user/42
    tmpfs                             383M   24K  383M    1% /run/user/1000

4.2.3 使用 du 命令
-----------------------------------------------------------------------------------------------------------------------------------------
du 命令可以显示某个特定目录(默认情况下是当前目录)的磁盘使用情况。这一方法可用来快速判断系统上某个目录下是否有超大文件。

默认情况下,du 命令会显示当前目录下所有的文件、目录和子目录的磁盘使用情况,它会以磁盘块为单位来表明每个文件或目录占用了多大存储空间。对
标准大小的目录来说,这个输出会是一个比较长的列表。

    [devalone@devalone shell-script]$ du
    64      ./15
    72      ./13
    24      ./24
    48      ./16
    12      ./.git/refs/remotes/origin
    16      ./.git/refs/remotes
    8       ./.git/refs/heads
    4       ./.git/refs/tags
    ...

每行输出左边的数值是每个文件或目录占用的磁盘块数。注意,这个列表是从目录层级的最底部开始,然后按文件、子目录、目录逐级向上。这么用 du 命令
(不加参数,用默认参数)作用并不大,下面是能让du命令用起来更方便的几个命令行参数。

    -c:显示所有已列出文件总的大小。
     -h:按用户易读的格式输出大小,即用 K 替代千字节,用 M 替代兆字节,用 G 替代吉字节。
    -s:显示每个输出参数的总计。

4.3 处理数据文件
-----------------------------------------------------------------------------------------------------------------------------------------


4.3.1 排序数据
-----------------------------------------------------------------------------------------------------------------------------------------
处理大量数据时的一个常用命令是 sort 命令,sort 命令是对数据进行排序的。默认情况下,sort 命令按照会话指定的默认语言的排序规则对文本文件中的
数据行排序。

    [devalone@devalone shell_test]$ cat sortfile
    1
    2
    100
    45
    3
    10
    145
    75

    [devalone@devalone shell_test]$ sort sortfile
    1
    10
    100
    145
    2
    3
    45
    75
默认情况下,sort 命令会把数字当做字符来执行标准的字符排序,产生的输出可能根本就不是要的。解决这个问题可用 -n 参数,它会告诉 sort 命令
把数字识别成数字而不是字符,并且按值排序。

    [devalone@devalone shell_test]$ sort -n sortfile
    1
    2
    3
    10
    45
    75
    100
    145

如期所愿了。

另一个常用的参数是 -M,按月排序。Linux 的日志文件经常会在每行的起始位置有一个时间戳,用来表明事件是什么时候发生的。-M 参数能识别三字符的
月份名,并相应地排序。

    [devalone@devalone shell_test]$ sort -M file
    Jan
    Feb
    Mar
    Apr
    May
    Jun
    Jul
    Aug
    Sep
    Oct
    Nov
    Dec

-k --key=POS1[,POS2] 排序从POS1位置开始;如果指定了POS2的话,到POS2位置结束。
-t --field-separator=SEP 指定一个用来区分键位置的字符。
-r --reverse 反序排序(升序变成降序)。

-k 和 -t 参数在对按字段分隔的数据进行排序时非常有用,例如/etc/passwd文件。可以用 -t 参数来指定字段分隔符,然后用-k 参数来指定排序的字段。
如对 /etc/passwd 文件根据用户 ID 进行数值排序,可以这么做:

    [devalone@devalone shell_test]$ sort -t ':' -k 3 -n /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    ...

-n 参数在排序数值时非常有用,比如 du 命令的输出:

    [devalone@devalone shell-script]$ du -sh * | sort -nr
    232K    network-scripts-zz
    172K    12
    128K    14
    72K     13
    68K     17
    64K     15
    56K     19
    52K     21
    52K     20
    48K     16
    32K     22
    28K     dirsh
    24K     24
    16K     23
    12K     18
    4.0K    testfile-zz
    4.0K    testfile

4.3.2 搜索数据
-----------------------------------------------------------------------------------------------------------------------------------------
经常需要在大文件中找一行数据,而这行数据又埋藏在文件的中间。这时并不需要手动翻看整个文件,用 grep 命令来帮助查找就行了。grep 命令的命令
格式如下:

    grep [options] pattern [file]

grep 命令会在输入或指定的文件中查找包含匹配指定模式的字符的行。grep 的输出就是包含了匹配模式的行。

    [devalone@devalone shell_test]$ grep 8th testfile
    This is the 8th line.

    [devalone@devalone shell_test]$ grep d testfile
    This is the second line.
    This is the third line.

如果要进行反向搜索(输出不匹配该模式的行),可加 -v 参数:

    [devalone@devalone shell_test]$ grep -v d testfile
    This is the first line.
    This is the fourth line.
    This is the 5th line.
    This is the 6th line.
    This is the 7th line.
    This is the 8th line.
    This is the 9th line.
    This is the 10th line.
    This is the 11th line.
    This is the 12th line.

要显示匹配模式的行所在的行号,可加 -n 参数。
    [devalone@devalone shell_test]$ grep -n d testfile
    2:This is the second line.
    3:This is the third line.

只要知道有多少行含有匹配的模式,可用 -c 参数。
    [devalone@devalone shell_test]$ grep -c d testfile
    2

    
如果要指定多个匹配模式,可用 -e 参数来指定每个模式:

    [devalone@devalone shell_test]$ grep -e d -e u testfile
    This is the second line.
    This is the third line.
    This is the fourth line.

    
默认情况下,grep 命令用基本的 Unix 风格正则表达式来匹配模式。Unix 风格正则表达式采用特殊字符来定义怎样查找匹配的模式。正则表达式的详细内容
会在后面章节说明。

使用正则表达式的例子:

    [devalone@devalone shell_test]$ grep [du] testfile
    This is the second line.
    This is the third line.
    This is the fourth line.
    
egrep 命令是 grep 的一个衍生,支持 POSIX 扩展正则表达式。POSIX 扩展正则表达式含有更多的可以用来指定匹配模式的字符。
fgrep 则是另外一个版本,支持将匹配模式指定为用换行符分隔的一列固定长度的字符串。这样就可以把这列字符串放到一个文件中,然后在 fgrep 命令中
用其在一个大型文件中搜索字符串了。


4.3.3 压缩数据
-----------------------------------------------------------------------------------------------------------------------------------------


    Linux文件压缩工具
    +-----------+---------------+------------------------------------------------------------
    | 工 具        | 文件扩展名    | 描 述
    +-----------+---------------+------------------------------------------------------------
    | bzip2        | .bz2            | 采用Burrows-Wheeler块排序文本压缩算法和霍夫曼编码
    +-----------+---------------+------------------------------------------------------------
    | compress    | .Z            | 最初的Unix文件压缩工具,已经快没人用了
    +-----------+---------------+------------------------------------------------------------
    | gzip        | .gz            | GNU压缩工具,用Lempel-Ziv编码
    +-----------+---------------+------------------------------------------------------------
    | zip        | .zip            | Windows上PKZIP工具的Unix实现
    +-----------+---------------+------------------------------------------------------------

gzip软件包是GNU项目的产物,软件包含有下面的工具:

    gzip:用来压缩文件。
    gzcat:用来查看压缩过的文本文件的内容。
    gunzip:用来解压文件。    

这些工具基本上跟 bzip2 工具的用法一样。

    [devalone@devalone shell_test]$ gzip testfile
    [devalone@devalone shell_test]$ ll testfile*
    -rw-rw-r--. 1 devalone devalone 105 7月   3 11:26 testfile.gz

gzip 命令会压缩在命令行指定的文件。也可以在命令行指定多个文件名甚至用通配符来一次性批量压缩文件。
    [devalone@devalone shell_test]$ gunzip test*

4.3.4 归档数据
-----------------------------------------------------------------------------------------------------------------------------------------
虽然zip命令能够很好地将数据压缩和归档进单个文件,但它不是 Unix 和 Linux 中的标准归档工具。Unix 和 Linux 上最广泛使用的归档工具是 tar 命令

tar 命令最开始是用来将文件写到磁带设备上归档的,然而它也能把输出写到文件里,这种用法在 Linux 上已经普遍用来归档数据了。

下面是tar命令的格式:

    tar function [options] object1 object2 ...

function 参数定义了 tar 命令应该做什么,如表所示:

    tar命令的功能
    +-------+---------------+--------------------------------------------------------------------------------
    | 功 能    | 长 名 称        | 描 述
    +-------+---------------+--------------------------------------------------------------------------------
    | -A    | --concatenate    | 将一个已有tar归档文件追加到另一个已有tar归档文件
    +-------+---------------+--------------------------------------------------------------------------------
    | -c    | --create        | 创建一个新的tar归档文件
    +-------+---------------+--------------------------------------------------------------------------------
    | -d    | --diff        | 检查归档文件和文件系统的不同之处
    +-------+---------------+--------------------------------------------------------------------------------
    | -r    | --append        | 追加文件到已有tar归档文件末尾
    +-------+---------------+--------------------------------------------------------------------------------
    | -t    | --list        | 列出已有tar归档文件的内容
    +-------+---------------+--------------------------------------------------------------------------------
    | -u    | --update        | 将比tar归档文件中已有的同名文件新的文件追加到该tar归档文件中
    +-------+---------------+--------------------------------------------------------------------------------
    | -x    | --extract        | 从已有tar归档文件中提取文件
    +-------+---------------+--------------------------------------------------------------------------------


    tar 命令选项
    +-----------+---------------------------------------
    | 选 项        | 描 述
    +-----------+---------------------------------------
    | -C dir    | 切换到指定目录
    +-----------+---------------------------------------
    | -f file    | 输出结果到文件或设备file
    +-----------+---------------------------------------
    | -j        | 将输出重定向给bzip2命令来压缩内容        
    +-----------+---------------------------------------
    | -p        | 保留所有文件权限
    +-----------+---------------------------------------
    | -v        | 在处理文件时显示文件
    +-----------+---------------------------------------
    | -z        | 将输出重定向给gzip命令来压缩内容
    +-----------+---------------------------------------


这些选项经常合并到一起使用。

创建一个归档文件:
    
    tar -cvf test.tar test/ test2/    

上面的命令创建了名为test.tar的归档文件,含有test和test2目录内容。

列出tar文件test.tar的内容:

    tar -tf test.tar

提取 test.tar 中的文件:

    tar -xvf test.tar
    
    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    下载到开源软件之后,经常会看到文件名以 .tgz 结尾,这些是 gzip 压缩的 tar 文件,可以用如下命令解压:
    
    tar -zxvf filename.tgz

系列目录: 

    走进 Linux shell (一)

    走进 Linux shell (二)

    走进 Linux shell (三)

参考:

    《Linux 命令行与 shell 脚本编程大全》 第 3 版 —— 2016.8(美)Richard Blum  Cristine Bresnahan

猜你喜欢

转载自blog.csdn.net/devalone/article/details/81111066