第一部分:学习 shell

如果shell提示符的最后一个字符是“#”,而不是“$”,说明当前终端会话具有超级用户权限。

Linux 基本命令

  • date:显示系统当前时间和日期。

    [root@izwz98bhvo3zyxk01i1qsiz admin]# date
    Thu Nov  7 00:11:32 CST 2019
  • cal:显示当前月份的日历。

    [root@izwz98bhvo3zyxk01i1qsiz admin]# cal
        November 2019   
    Su Mo Tu We Th Fr Sa
                    1  2
     3  4  5  6  7  8  9
    10 11 12 13 14 15 16
    17 18 19 20 21 22 23
    24 25 26 27 28 29 30
  • df:查看磁盘剩余空间的大小。

-h:等同于 --human-readable,以人类可读的格式而不是字节数来显示文件大小。

[root@izwz98bhvo3zyxk01i1qsiz admin]# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/vda1       41151808 5790188  33248188  15% /
devtmpfs          931516       0    931516   0% /dev
tmpfs             941860       0    941860   0% /dev/shm
tmpfs             941860   98680    843180  11% /run
tmpfs             941860       0    941860   0% /sys/fs/cgroup
tmpfs             188376       0    188376   0% /run/user/0
tmpfs             188376       0    188376   0% /run/user/1002
tmpfs             188376       0    188376   0% /run/user/1003
[root@izwz98bhvo3zyxk01i1qsiz admin]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  5.6G   32G  15% /
devtmpfs        910M     0  910M   0% /dev
tmpfs           920M     0  920M   0% /dev/shm
tmpfs           920M   97M  824M  11% /run
tmpfs           920M     0  920M   0% /sys/fs/cgroup
tmpfs           184M     0  184M   0% /run/user/0
tmpfs           184M     0  184M   0% /run/user/1002
tmpfs           184M     0  184M   0% /run/user/1003
  • free:显示空闲内存的大小。

    [root@izwz98bhvo3zyxk01i1qsiz admin]# free
    total        used        free      shared  buff/cache   available
    Mem:        1883724      502472      142184      120256     1239068     1054624
    Swap:             0           0           0
    [root@izwz98bhvo3zyxk01i1qsiz admin]# free -h
    total        used        free      shared  buff/cache   available
    Mem:           1.8G        490M        138M        117M        1.2G        1.0G
    Swap:            0B          0B          0B
  • exit:关闭当前会话。

文件系统中跳转

  • pwd:查看当前工作目录。

    [root@izwz98bhvo3zyxk01i1qsiz www]# pwd
    /home/www
  • cd:更改工作目录。

    [root@izwz98bhvo3zyxk01i1qsiz www]# pwd
    /home/www
    [root@izwz98bhvo3zyxk01i1qsiz www]# cd htdocs/usr/uploads/
    [root@izwz98bhvo3zyxk01i1qsiz uploads]# pwd
    /home/www/htdocs/usr/uploads
    [root@izwz98bhvo3zyxk01i1qsiz uploads]# cd -        % 更改工作目录到之前的工作目录
    /home/www
    [root@izwz98bhvo3zyxk01i1qsiz www]# pwd
    /home/www
    [root@izwz98bhvo3zyxk01i1qsiz www]# cd        % 更改工作目录到家目录
    [root@izwz98bhvo3zyxk01i1qsiz ~]# pwd
    /root
  • ls:列出目录内容。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls
    env.txt  sa_recovery.log  sa_recovery.log.bak
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls /home /sys        % 列出多个目录
    /home:
    admin  staragent  www
    
    /sys:
    block  class  devices   fs          kernel  power
    bus    dev    firmware  hypervisor  module
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -a        % 列出隐藏文件
    .              .bash_profile  env.txt            .pydistutils.cfg     .tcshrc
    ..             .bashrc        .mysql_history     sa_recovery.log      .viminfo
    .bash_history  .cache         .oracle_jre_usage  sa_recovery.log.bak
    .bash_logout   .cshrc         .pip               .ssh
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l        % 以长格式输出
    total 1040
    -r-x------ 1 root root     141 Apr 24  2019 env.txt
    -rw-r--r-- 1 root root   51652 Nov  7 00:30 sa_recovery.log
    -rw-r--r-- 1 root root 1000013 Nov  5 08:20 sa_recovery.log.bak
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -ld        % 列出目录本身的详细信息,而非目录中的内容
    dr-xr-x---. 6 root root 4096 Nov  7 00:39 .
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -li        % 显示文件索引节点信息
    total 1040
    132523 -r-x------ 1 root root     141 Apr 24  2019 env.txt
    132542 -rw-r--r-- 1 root root   54648 Nov  7 02:50 sa_recovery.log
    132540 -rw-r--r-- 1 root root 1000013 Nov  5 08:20 sa_recovery.log.bak
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -r        % 以相反的顺序来显示结果
    sa_recovery.log.bak  sa_recovery.log  env.txt
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -S        % 按文件大小排列输出结果
    sa_recovery.log.bak  sa_recovery.log  env.txt
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -t        % 按修改时间排列输出结果
    sa_recovery.log  sa_recovery.log.bak  env.txt

深入研究长格式输出,如下例:

[root@izwz98bhvo3zyxk01i1qsiz htdocs]# ls -l
total 96
drwxr-xr-x 5 root root  4096 Apr 24  2019 admin
drwxr-xr-x 6 root root  4096 Apr 24  2019 build
-rw-r--r-- 1 www  www   1556 Apr 24  2019 config.inc.php
-rw-r--r-- 1 root root    53 Jul 28 16:12 googlee87a564af9131572.html
-rw-r--r-- 1 root root   721 Apr 24  2019 index.php
drwxr-xr-x 2 root root  4096 Apr 24  2019 install
-rw-r--r-- 1 root root 48403 Apr 24  2019 install.php
-rw-r--r-- 1 root root 14974 Apr 24  2019 LICENSE.txt
drwxr-xr-x 6 root root  4096 Apr 27  2019 usr
drwxr-xr-x 5 root root  4096 Apr 24  2019 var

各输出字段含义:

| 字段 | 含义 |
| :----------: | :----------------------------------------------------------: |
| -rw-r--r-- | 对于文件的访问权限。第一个字符指明文件类型,“-”表示普通文件,“d”表示目录。其后三个字符是文件所有者的访问权限,再其后的三个字符是文件所属组中成员的访问权限,最后三个字符是其他所有人的访问权限。 |
| 1 | 文件的硬链接数目。 |
| root | 文件所有者的用户名。 |
| root | 文件所属用户组的名字。 |
| 4096 | 文件大小。 |
| Apr 24 2019 | 上次修改文件的时间和日期。 |
| install.php | 文件名。 |

操作文件和目录

常用操作命令

通配符(wildcard):

通配符含义
*匹配任意多个字符(包括零个或一个)
?匹配任意一个字符(不包括零个)
[characters]匹配任意一个属于字符集中的字符
[!characters]匹配任意一个不是字符集中的字符
[[:class:]]匹配任意一个属于指定字符类中的字符

常用字符类:

字符类含义
[:alnum:]匹配任意一个字母或数字
[:alpha:]匹配任意一个字母
[:digit:]匹配任意一个数字
[:lower:]匹配任意一个小写字母
[:upper:]匹配任意一个大写字母
  • file:确定文件类型。

    [root@izwz98bhvo3zyxk01i1qsiz htdocs]# file index.php
    index.php: PHP script, UTF-8 Unicode text
    [root@izwz98bhvo3zyxk01i1qsiz htdocs]# file ./var
    ./var: directory
  • less:浏览文本文件内容。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# less sa_recovery.log
    ==================2019-11-05 08:25:01====================
    using bash as default shell
    agent is running ok 
    ==================2019-11-05 08:30:01====================
    using bash as default shell
    agent is running ok 
    ==================2019-11-05 08:35:01====================
    using bash as default shell
    agent is running ok 
    ==================2019-11-05 08:40:01====================
    using bash as default shell
    agent is running ok
    ...

less 常用键盘命令:

| 命令 | 行为 |
| :----------------: | :------------------------: |
| Page UP or b | 向上翻滚一页 |
| Page Down or space | 向下翻滚一页 |
| UP Arrow | 向上翻滚一行 |
| Down Arrow | 向下翻滚一行 |
| G | 移动到最后一行 |
| 1G or g | 移动到开头一行 |
| /charaters | 向前查找指定的字符串 |
| n | 向前查找下一个出现的字符串 |
| h | 显示帮助屏幕 |
| q | 退出 less 程序 |

  • mkdir:创建目录。
  • cp:复制文件或目录。

常用参数:

-a:复制文件和目录,以及它们的属性,包括所有权和权限。

-i:在重写已存在文件之前,提示用户确认。如果不指定此选项,则默认会重写文件。

-r:递归地复制目录及目录中的内容。复制目录时需要这个选项(或者 -a 选项)。

-u:仅复制目标目录中不存在的文件,或者文件内容新于目标目录中已经存在的文件。

-v:显示翔实的命令操作信息。

  • mv:移动或重命名文件。

常用参数:

-i:在重写已存在文件之前,提示用户确认。如果不指定此选项,则默认会重写文件。

-u:仅移动目标目录中不存在的文件,或者文件内容新于目标目录中已经存在的文件。

-v:显示翔实的命令操作信息。

  • rm:删除文件或目录。

常用参数:

-i:在删除已存在文件之前,提示用户确认。如果不指定此选项,则直接删除。

-r:递归地删除目录及目录中的内容。

-f:忽视不存在的文件,不显示提示信息。

-v:显示翔实的命令操作信息。

Linux 系统中的目录

  • /:根目录,万物起源。
  • /bin:包含系统启动和运行所必须的二进制程序。
  • /boot:包含 Linux 内核、初始 RAM 磁盘映像(用于启动时所需的驱动)和启动加载程序。

    • /boot/grub/grub.conf or menu.lst:被用来配置启动加载程序。
    • /boot/vmlinuz:Linux 内核。
  • /dev:包含设备结点的特殊目录,在这个目录里,内核维护着所有设备的列表。
  • /etc:包含所有系统层面的配置文件。它也包含一系列的 shell 脚本,在系统启动时,这些脚本会开启每个系统服务。这个目录中的任何文件应该是可读的文本文件。

    • /etc/crontab:定义自动运行的任务。
    • /etc/fstab:包含存储设备的列表,以及与他们相关的挂载点。
    • /etc/passwd:包含用户帐号列表。
  • /home:在通常的配置环境下,系统会在 /home 下,给每个用户分配一个目录。普通用户只能在自己的目录下写文件。
  • lib:包含核心系统程序所使用的共享库文件。
  • /lost+found:每个使用 Linux 文件系统的格式化分区或设备,例如 ext3 文件系统,都会有这个目录。当部分恢复一个损坏的文件系统时会用到这个目录。这个目录应该是空的,除非文件系统真的损坏了。
  • /media:在现在的 Linux 系统中,/media` 目录会包含可移动介质的挂载点, 例如 USB 驱动器,CD-ROMs 等等。这些介质连接到计算机之后,会自动地挂载到这个目录结点下。
  • /mnt:在早些的 Linux 系统中,/mnt 目录包含可移动介质的挂载点。
  • /opt:该目录被用来安装“可选的”软件。主要用来存储可能安装在系统中的商业软件产品。
  • /proc:这个目录很特殊,从存储在硬盘上的文件的意义上说,它不是真正的文件系统。相反,它是一个由 Linux 内核维护的虚拟文件系统。它所包含的文件是内核的窥视孔,这些文件是可读的,它们会告诉你内核是怎样监管计算机的。
  • /root:root 帐户的家目录。
  • /sbin:包含“系统”二进制文件,它们是完成重大系统任务的程序,通常为超级用户保留。
  • /tmp:用来存储由各种程序创建的临时文件。一些配置导致系统每次重新启动时,都会清空这个目录。
  • /usr:包含普通用户所需要的所有程序和文件。
  • /usr/bin:包含系统安装的可执行程序。
  • /usr/lib:包含由 /usr/bin 目录中的程序所用的共享库。
  • /usr/local:非系统发行版自带程序的安装目录。通常,由源码编译的程序会安装在 /usr/local/bin 目录下。新安装的 Linux 系统中会存在这个目录, 并且在管理员安装程序之前,这个目录是空的。
  • /usr/sbin:包含许多系统管理程序。
  • /usr/share:包含许多由 /usr/bin 目录中的程序使用的共享数据。例如默认的配置文件、图标、桌面背景、音频文件等。
  • /usr/share/doc:包含系统中安装的软件的文档。
  • /var:存放动态文件。各种数据库、假脱机文件、用户邮件等都位于这里。
  • /var/log:包含日志文件、各种系统活动的记录。这些文件非常重要,应该时时监测它们,其中最重要的一个文件是 /var/log/messages。在一些系统中,只有超级用户才能查看这些日志文件。

符号链接与硬链接

在查看文件时,有时我们会看到类似于下面的信息:

lrwxrwxrwx  1 root root    20 Aug  7 00:59 cuda -> /usr/local/cuda-10.0

第一个字符是“l”,说明这是一个特殊文件:符号链接(也称为软链接或 symlink)。符号链接的作用是,如果安装了同一文件的多个版本,我们可以让其他使用该文件的程序使用符号链接来调用该文件,而非直接打开该文件本身。这样便于在多个版本之间切换,只需要更改符号链接的指向就可以了。

与更加现代的符号链接相比,硬链接是最初 Unix 创建链接的方式。每个文件默认会有一个硬链接,这个硬链接给予文件名字。我们每创建一个硬链接,就为一个文件创建了一个额外的目录项。 然而,硬链接有两个重要局限性:一个硬链接不能关联它所在文件系统之外的文件,即不能关联与链接本身不在同一个磁盘分区上的文件;同时,硬链接不能关联一个目录。

  • ln:创建链接。

创建符号链接(软链接):

ln -s file link

创建硬链接:

ln item link

识别与使用命令

什么是命令?命令可以是下面四种形式之一:

  • 一个可执行程序。
  • 一个内建于 shell 自身的命令,例如 cd
  • 一个 shell 函数。
  • 一个命令别名。

常用命令操作:

  • type:显示命令的类型。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# type cd
    cd is a shell builtin
    [root@izwz98bhvo3zyxk01i1qsiz ~]# type sudo
    sudo is /bin/sudo
    [root@izwz98bhvo3zyxk01i1qsiz ~]# type ls
    ls is aliased to `ls --color=auto'
  • which:显示一个可执行程序的位置。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# which python
    /bin/python
    [root@izwz98bhvo3zyxk01i1qsiz ~]# which pip
    /bin/pip
  • help:得到 shell 内建命令的帮助文档。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# help cd
    cd: cd [-L|[-P [-e]]] [dir]
        Change the shell working directory.
        
        Change the current directory to DIR.  The default DIR is the value of the
        HOME shell variable.
        
        The variable CDPATH defines the search path for the directory containing
        DIR.  Alternative directory names in CDPATH are separated by a colon (:).
        A null directory name is the same as the current directory.  If DIR begins
        with a slash (/), then CDPATH is not used.
        
        If the directory is not found, and the shell option `cdable_vars' is set,
        the word is assumed to be  a variable name.  If that variable has a value,
        its value is used for DIR.
        
        Options:
            -L force symbolic links to be followed
            -P use the physical directory structure without following symbolic
         links
            -e if the -P option is supplied, and the current working directory
         cannot be determined successfully, exit with a non-zero status
        
        The default is to follow symbolic links, as if `-L' were specified.
        
        Exit Status:
        Returns 0 if the directory is changed, and if $PWD is set successfully when
        -P is used; non-zero otherwise.

许多可执行程序支持一个 --help 选项,可以显示用法信息:

[root@izwz98bhvo3zyxk01i1qsiz ~]# mkdir --help
Usage: mkdir [OPTION]... DIRECTORY...
Create the DIRECTORY(ies), if they do not already exist.

Mandatory arguments to long options are mandatory for short options too.
  -m, --mode=MODE   set file mode (as in chmod), not a=rwx - umask
  -p, --parents     no error if existing, make parent directories as needed
  -v, --verbose     print a message for each created directory
  -Z                   set SELinux security context of each created directory
                         to the default type
      --context[=CTX]  like -Z, or if CTX is specified then set the SELinux
                         or SMACK security context to CTX
      --help     display this help and exit
      --version  output version information and exit

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'mkdir invocation'
  • man:显示应用程序手册页。这是一种正式的文档。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# man rm
    RM(1)                           User Commands                           RM(1)
    
    NAME
    rm - remove files or directories
    
    SYNOPSIS
    rm [OPTION]... FILE...
    
    DESCRIPTION
    This  manual  page  documents  the GNU version of rm.  rm removes each
    specified file.  By default, it does not remove directories.
    
    If the -I or --interactive=once option is given, and  there  are  more
    than  three  files  or  the  -r, -R, or --recursive are given, then rm
    prompts the user for whether to proceed with the entire operation.  If
    the response is not affirmative, the entire command is aborted.
    
    Otherwise,  if a file is unwritable, standard input is a terminal, and
    the -f or --force option  is  not  given,  or  the  -i  or  --interac‐
    tive=always option is given, rm prompts the user for whether to remove
    the file.  If the response is not affirmative, the file is skipped.
    ...

手册页的组织形式:

| 章节 | 内容 |
| :--: | :----------------------------: |
| 1 | 用户命令 |
| 2 | 程序接口内核系统调用 |
| 3 | C 库函数程序接口 |
| 4 | 特殊文件,如设备结点和驱动程序 |
| 5 | 文件格式 |
| 6 | 游戏娱乐,如屏幕保护程序 |
| 7 | 其他方面 |
| 8 | 系统管理员命令 |

  • apropos:根据关键字搜索手册页,显示匹配的命令。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# apropos CPU
    chcpu (8)            - configure CPUs
    cpupower (1)         - Shows and sets processor power related values
    cpupower-frequency-info (1) - (unknown subject)
    cpupower-frequency-set (1) - (unknown subject)
    cpupower-idle-info (1) - (unknown subject)
    cpupower-idle-set (1) - (unknown subject)
    cpupower-info (1)    - Shows processor power related kernel or hardware conf...
    cpupower-monitor (1) - Report processor frequency and idle statistics
    cpupower-set (1)     - Set processor power related kernel or hardware config...
    iostat (1)           - Report Central Processing Unit (CPU) statistics and i...
    lscpu (1)            - display information about the CPU architecture
    taskset (1)          - retrieve or set a process's CPU affinity
  • whatis:显示匹配特定关键字的手册页的名字和一行命令说明:

    [root@izwz98bhvo3zyxk01i1qsiz ~]# whatis ln
    ln (1)               - make links between files
    [root@izwz98bhvo3zyxk01i1qsiz ~]# whatis whatis
    whatis (1)           - display manual page descriptions
  • info:显示程序的 info 条目。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# info which
    File: which.info,  Node: Top,  Next: Which Program,  Prev: (dir),  Up: (dir)
    
    `which': Show the full path of commands
    ***************************************
    
    The `which' program shows the full path of (shell) commands.
    
    This file documents `which' version 2.20, updated 16 January 2008.
    
    * Menu:
    
    * Which Program::               The `which' Program
    * Invoking Which::              How to invoke `which'
    * Option Summary::              Overview of commandline options
    * Return Value::                The return value of `which'
    * Example::                     Examples of invokation
    * Bugs::                        Known bugs
    * See Also::                    Related UNIX commands
    * Index::                       Index
    ...
  • alias:创建命令别名。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# alias enter='cd /home/www/htdocs; ls; cd ..; pwd'
    [root@izwz98bhvo3zyxk01i1qsiz ~]# enter
    admin  config.inc.php               index.php  install.php  usr
    build  googlee87a564af9131572.html  install    LICENSE.txt  var
    /home/www
    [root@izwz98bhvo3zyxk01i1qsiz www]# 

unalias:删除命令别名。

[root@izwz98bhvo3zyxk01i1qsiz ~]# unalias enter
[root@izwz98bhvo3zyxk01i1qsiz ~]# enter
bash: enter: command not found

重定向

程序的输出有两种类型:

  • 程序运行结果,即程序要完成的功能。
  • 状态和错误信息,这些告诉我们程序进展。

与 Unix “一切皆文件”的主题保持一致,程序实际上把他们的运行结果输送到一个叫做标准输出 stdout 的特殊文件,而它们的状态信息则送到另一个叫做标准错误 stderr 的文件。默认情况下,标准输出和标准错误都连接到屏幕,而不是保存到磁盘文件。除此之外,许多程序从一个叫做标准输入 stdin 的设备得到输入,默认情况下,标准输入连接到键盘。

通过 I/O 重定向,我们可以更改输出目标和输入来源。

标准输出重定向

我们使用 > 重定向符后接文件名将标准输出重定向到除屏幕以外的另一个文件。例如:

[root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l > output.txt
[root@izwz98bhvo3zyxk01i1qsiz ~]# less output.txt
total 1100
-r-x------ 1 root root     141 Apr 24  2019 env.txt
-rw-r--r-- 1 root root       0 Nov  9 01:28 output.txt
-rw-r--r-- 1 root root  114461 Nov  9 01:25 sa_recovery.log
-rw-r--r-- 1 root root 1000013 Nov  5 08:20 sa_recovery.log.bak

我们现在只重定向了标准输出,而没有重定向标准错误,因此命令如果出错,则输出将被重写,但由于命令没有产生运行结果,因此重写文件开始后立刻被终止,这会导致文件内容被清空。

事实上,我们可以使用以下技巧来清空一个文件的内容(或创建一个新的文件):

[root@izwz98bhvo3zyxk01i1qsiz ~]# > output.txt

> 不同,使用 >> 操作符会把重定向结果追加到文件内容后面,而非重写文件:

[root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l >> output.txt

如果文件不存在,>> 操作符会跟 > 一样创建一个新的文件。

标准错误重定向

标准错误没有专用的重定向操作符,但我们可以使用“文件描述符”来完成重定向操作。一个程序可以在一组具有编号的“文件流”中的任一个上产生输出,前三个文件流就是标准输入、输出和错误,shell 内部分别将其称为文件描述符0、1和2。因为标准错误等价于文件描述符2,我们可以据此来重定向标准错误:

[root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l ./not_exist_dir 2> error.txt

重定向标准输出和错误到同一个文件

有时,我们希望将一个命令的所有输出保存到同一个文件,这需要同时重定向标准输出和标准错误。

  • 方法一:较为传统的方法。首先重定向标准输出到文件,然后重定向文件描述符2(标准错误)到文件描述符1(标准输出)。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l ./some_dir > error.txt 2>&1

要注意重定向的顺序,标准错误的重定向必须在标准输出之后。

  • 方法二:较新版本的 bash 提供的更精简的方法。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l ./some_dir &> error.txt

处理不需要的输出

有时候我们不关心一个命令的输出,希望将它“沉默”掉。我们可以将命令的输出或错误重定向到一个特殊文件 /dev/null 来达到这个目的。该文件是系统设备,称为“位存储桶”,它可以接受输入,但对输入不做任何处理。

[root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l ./some_dir 2> /dev/null

标准输入重定向

管道线

shell 具有一种被称为管道线(pipeline)的特性,通过使用管道操作符 |,一个命令的标准输出可以通过管道送至另一个命令的标准输入:

[root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l /usr/lib | less
total 120
drwxr-xr-x.  2 root root  4096 May 26  2017 binfmt.d
drwxr-xr-x   2 root root  4096 Aug 18  2017 cloud-init
lrwxrwxrwx   1 root root    10 Aug 18  2017 cpp -> ../bin/cpp
drwxr-xr-x.  3 root root  4096 Nov  5  2016 debug
drwxr-xr-x.  4 root root  4096 Aug 18  2017 dracut
drwxr-xr-x.  7 root root  4096 May 26  2017 firewalld
drwxr-xr-x. 77 root root 12288 Aug 18  2017 firmware
:

使用这项技术,我们可以方便地检测产生标准输出的任一命令的运行结果。

过滤器

管道线经常用来对数据完成复杂的操作。有时,我们会把几个命令放在一起组成一个管道线,以这种方式使用的命令被称为过滤器。过滤器接受输入,以某种方式改变它,然后输出它。

[root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l /usr/bin | sort | less
lrwxrwxrwx  1 root root        10 Aug 18  2017 bashbug -> bashbug-64
lrwxrwxrwx  1 root root        11 Aug 18  2017 systemd-coredumpctl -> coredumpctl
lrwxrwxrwx. 1 root root        13 Aug 18  2017 rpmquery -> ../../bin/rpm
lrwxrwxrwx. 1 root root        13 Aug 18  2017 rpmverify -> ../../bin/rpm
lrwxrwxrwx  1 root root        15 Aug 18  2017 Mail -> ../../bin/mailx
lrwxrwxrwx  1 root root        15 Aug 18  2017 nail -> ../../bin/mailx
lrwxrwxrwx  1 root root        19 Aug 18  2017 setup-nsssysinit -> setup-nsssysinit.sh
:

一些常用命令:

  • cat:读取一个或多个文件,然后复制到标准输出。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# cat log.txt        % 常用于查看简短的文本文件
    apache_dir:/usr/local/apache
    mysql_dir:/usr/local/mysql
    php_dir:/usr/local/php56
    [root@izwz98bhvo3zyxk01i1qsiz ~]# cat dataset.tar.gz.00* > dataset.tar.gz        % 合并文件
    [root@izwz98bhvo3zyxk01i1qsiz ~]# cat        % 无参数时,等待来自标准输入(键盘)的数据
    I am so handsome    % 按ctrl+d结束输入
    I am so handsome

我们可以使用 < 操作符重定向标准输入:

[root@izwz98bhvo3zyxk01i1qsiz ~]# cat < log.txt
apache_dir:/usr/local/apache
mysql_dir:/usr/local/mysql
php_dir:/usr/local/php56

可以看出结果与不加 < 一样,但这不代表这种重定向标准输入的方式没有意义。

  • sort:排序文本行。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l /usr/bin | sort | less
  • uniq:报道或忽略重复行。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l /usr/bin | sort | uniq | less
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls -l /usr/bin | sort | uniq -d | less        % 列出重复数据的列表
  • wc:打印行数、字数和字节数。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# wc env.txt
      5   5 141 env.txt
    [root@izwz98bhvo3zyxk01i1qsiz ~]# wc -l env.txt     % 只打印行数
    5 env.txt
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls /bin /usr/bin | sort | uniq | wc -l    % 统计程序个数
    768
  • grep:找到文件中的匹配文本,并打印匹配行。

用法:grep pattern [file...]

[root@izwz98bhvo3zyxk01i1qsiz ~]# grep license index.php
 * @license    GNU General Public License 2.0
[root@izwz98bhvo3zyxk01i1qsiz ~]# grep license index.php
 * @license    GNU General Public License 2.0
[root@izwz98bhvo3zyxk01i1qsiz ~]# ls /bin /usr/bin | sort | uniq | grep zip    % 列出所有名称包含'zip'的程序
funzip
gpg-zip
gunzip
gzip
unzip
unzipsfx
zip
zipcloak
zipgrep
zipinfo
zipnote
zipsplit
[root@izwz98bhvo3zyxk01i1qsiz ~]# grep -i license index.html        % 搜索时忽略大小写
[root@izwz98bhvo3zyxk01i1qsiz ~]# grep -v license index.html        % 只打印不匹配的行
  • head/tail:打印文件开头/结尾部分。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# head log.txt    % 默认打印前10行
    ==================2019-11-05 08:25:01====================
    using bash as default shell
    agent is running ok 
    ==================2019-11-05 08:30:01====================
    using bash as default shell
    agent is running ok 
    ==================2019-11-05 08:35:01====================
    using bash as default shell
    agent is running ok 
    ==================2019-11-05 08:40:01====================
    [root@izwz98bhvo3zyxk01i1qsiz ~]# head -n 2 log.txt        % 指定打印前n行
    ==================2019-11-05 08:25:01====================
    using bash as default shell
    [root@izwz98bhvo3zyxk01i1qsiz ~]# tail log.txt    % 默认打印后10行
    agent is running ok 
    ==================2019-11-09 03:30:01====================
    using bash as default shell
    agent is running ok 
    ==================2019-11-09 03:35:01====================
    using bash as default shell
    agent is running ok 
    ==================2019-11-09 03:40:01====================
    using bash as default shell
    agent is running ok
    [root@izwz98bhvo3zyxk01i1qsiz ~]# tail -n 2 log.txt        % 指定打印后n行
    using bash as default shell
    agent is running ok
    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls /bin /usr/bin | sort | uniq | grep zip | tail -n 5        % 用于管道线中
    zipcloak
    zipgrep
    zipinfo
    zipnote
    zipsplit
    [root@izwz98bhvo3zyxk01i1qsiz ~]# tail -f log.txt        % 监测文件并实时浏览,ctrl+c停止
    using bash as default shell
    agent is running ok
    ...
  • tee:从 stdin 读取数据,并同时输出到 stdout 和文件。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# ls /usr/bin | tee ls.txt | grep zip
    funzip
    gpg-zip
    gunzip
    gzip
    unzip
    unzipsfx
    zip
    zipcloak
    zipgrep
    zipinfo
    zipnote
    zipsplit
    [root@izwz98bhvo3zyxk01i1qsiz ~]# cat ls.txt | wc -l
    765

shell 中的展开

  • echo:显示一行文本

字符展开

[root@izwz98bhvo3zyxk01i1qsiz ~]# echo *
env.txt ls.txt sa_recovery.log sa_recovery.log.bak

路径名展开

[root@izwz98bhvo3zyxk01i1qsiz ~]# echo /usr/*/bin
/usr/local/bin

波浪线展开

波浪线会展开为家目录。

[root@izwz98bhvo3zyxk01i1qsiz ~]# echo ~
/root

算术表达式展开

算术表达式展开的格式为:

$((expression))
[root@izwz98bhvo3zyxk01i1qsiz ~]# echo $((2 + 2))
4

支持的算术操作符:+、-、、/、%、*。

花括号展开

[root@izwz98bhvo3zyxk01i1qsiz ~]# echo Front-{A,B,C}-Back
Front-A-Back Front-B-Back Front-C-Back
[root@izwz98bhvo3zyxk01i1qsiz ~]# echo Number_{1..5}
Number_1 Number_2 Number_3 Number_4 Number_5
[root@izwz98bhvo3zyxk01i1qsiz ~]# echo {Z..A}
Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
[root@izwz98bhvo3zyxk01i1qsiz pics]# mkdir {2007..2009}-0{1..9} {2007..2009}-{10..12}
[root@izwz98bhvo3zyxk01i1qsiz pics]# ls
2007-01 2007-07 2008-01 2008-07 2009-01 2009-07
2007-02 2007-08 2008-02 2008-08 2009-02 2009-08
2007-03 2007-09 2008-03 2008-09 2009-03 2009-09
2007-04 2007-10 2008-04 2008-10 2009-04 2009-10
2007-05 2007-11 2008-05 2008-11 2009-05 2009-11
2007-06 2007-12 2008-06 2008-12 2009-06 2009-12

参数展开

[root@izwz98bhvo3zyxk01i1qsiz ~]# echo $USER
root

命令替换

命令替换允许把一个命令的输出作为一个展开模式来使用。

[root@izwz98bhvo3zyxk01i1qsiz ~]# echo $(ls)
env.txt ls.txt sa_recovery.log sa_recovery.log.bak
[root@izwz98bhvo3zyxk01i1qsiz ~]# file $(ls /usr/bin/* | grep zip)
/usr/bin/funzip:   ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=ef1ea80700a87f14916159ef67bad874027098a8, stripped
/usr/bin/gpg-zip:  POSIX shell script, ASCII text executable
/usr/bin/gunzip:   POSIX shell script, ASCII text executable
/usr/bin/gzip:     ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=a4398a4411db835cf490289a81f65c1c3fc8c2b8, stripped
/usr/bin/unzip:    ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=1c3fbcdc3a4d4c5504b101befd6543cc512f8c54, stripped
...

也可以使用倒引号进行命令替换:

[root@izwz98bhvo3zyxk01i1qsiz ~]# file `ls /usr/bin/* | grep zip`
/usr/bin/funzip:   ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=ef1ea80700a87f14916159ef67bad874027098a8, stripped
/usr/bin/gpg-zip:  POSIX shell script, ASCII text executable
/usr/bin/gunzip:   POSIX shell script, ASCII text executable
/usr/bin/gzip:     ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=a4398a4411db835cf490289a81f65c1c3fc8c2b8, stripped
/usr/bin/unzip:    ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=1c3fbcdc3a4d4c5504b101befd6543cc512f8c54, stripped
...

引用

shell提供了一种叫做引用的机制,来有选择地禁止不需要的展开。

双引号

如果把文本放在双引号中,特殊字符会失去它们的特殊含义,被当作普通字符来看待。 但 $\,倒引号除外。使用双引号可以阻止单词分割 。

[root@izwz98bhvo3zyxk01i1qsiz ~]# mv "two words.txt" two_words.txt
单引号

使用单引号可以禁止所有的展开。

[root@izwz98bhvo3zyxk01i1qsiz ~]# echo '$USER'
$USER
转义字符

可以使用 \ 转移单个字符避免展开。

[root@izwz98bhvo3zyxk01i1qsiz ~]# echo "The balance for user $USER is: \$5.00"
The balance for user root is: $5.00

键盘的高级操作

注:Macbook终端中需要把含有 Alt 的操作改为 Esc

移动光标

按键操作
Ctrl-a移动光标到行首
Ctrl-e移动光标到行尾
Ctrl-f光标前移一个字符
Ctrl-b光标后移一个字符
Alt-f光标前移一个字
Alt-b光标后移一个字
Ctrl-l清空屏幕,移动光标到左上角

修改文本

按键操作
Ctrl-d删除光标位置的字符
Ctrl-t光标位置的字符和光标前面的字符互换位置
Alt-t光标位置的字和其前面的字互换位置
Alt-l把从光标位置到字尾的字符转换成小写字母
Alt-u把从光标位置到字尾的字符转换成大写字母
Alt-c使当前字首字母大写

剪切和粘贴文本

shell 使用术语 killing 和 yanking 来指剪切和粘贴,剪切下来的本文被存储在一个叫做剪切环(kill-ring)的缓冲区中。

按键操作
Ctrl-k剪切从光标位置到行尾的文本
Ctrl-u剪切从光标位置到行首的文本
Alt-d剪切从光标位置到词尾的文本
Alt-Backspace剪切从光标位置到词头的文本;如果光标在一个单词的开头,剪切前一个单词
Ctrl-y把剪切环中的文本粘贴到光标位置

利用历史命令

在默认情况下,bash 会存储所输入过的最后500个命令。

  • history:查看历史命令列表。

    [root@izwz98bhvo3zyxk01i1qsiz ~]# history | grep /usr/bin
    565  ls -l /usr/bin | less
    566  ls -l /usr/bin | sort |less
    572  ls /bin /usr/bin | sort | uniq | wc -l
    577  ls /bin /usr/bin | sort | uniq | grep zip
    588  ls /bin /usr/bin | sort | uniq | grep zip | tail -n 5
    589  ls /usr/bin | tee ls.txt | grep zip
    613  file $(ls /usr/bin/* | grep zip)
    615  file `ls /usr/bin/* | grep zip`
    621  history | grep /usr/bin
历史命令搜索
按键操作
Ctrl-p移动到上一个历史条目
Ctrl-n移动到下一个历史条目
Alt-<移动到历史列表开头
Alt->移动到历史列表结尾,即当前命令行
Ctrl-r进入反向增量搜索
Ctrl-j复制搜索结果到当前命令行
Alt-p反向搜索,非增量搜索
Alt-n向前搜索,非增量
Ctrl-o执行历史列表中的当前项,并移到下一个
历史命令展开
序列操作
!!重复最后一次执行的命令
!number重复历史列表中第 number 行的命令
!string重复最近历史列表中以这个字符串开头的命令
!?string重复最近历史列表中包含这个字符串的命令
[root@izwz98bhvo3zyxk01i1qsiz ~]# !588
ls /bin /usr/bin | sort | uniq | grep zip | tail -n 5
zipcloak
zipgrep
zipinfo
zipnote
zipsplit
Last modification:November 15th, 2019 at 01:16 pm
如果觉得我的文章对你有用,请随意赞赏