框架:

    bash的引用:命令引用、变量引用

    bash命令历史

    bash中的通配符

    bash中的管道

    I/O重定向

    命令补全

    路径补全

    bash的快捷键

    命令的别名

    命令行的展开

    

1)命令的执行结果与命令的执行状态结果

     命令的执行结果:

用户输入命令+Enter后,命令如何执行

    命令提示符,回车键后:bash切片,分析命令,[选项],参数,提请给内核,分配资源,运行为一个进程 wKioL1l8IiPT_kV7AAB0vWKIn1A080.png

    1)用户接口(bash程序)解析用户输入的命令

        先在hash中查找,然后在PATH中查找,路径下是否有此命令?

    2)对命令词法分析和语法分析:

         选项,参数是否正确?

    3)以上确认无误后,将命令所处的路径,提交给内核,内核将内核分配给指令CPU时间片、内存资源,将其运行为进程

        3.1)内核将此路径下的程序从磁盘中加载至内存中,(程序=指令+数据,所以内存的进程地址空间指令和数据,对应的物理内存中的指令和数据可能是不连续的几段内存页)

        3.2)内核将指令到CPU上运行,指令自动调用CPU的针脚指令(普通指令)完成某些功能,如果需要特权指令,将向内核发起syscall,完成相应的功能,并将生成的结果保存至内存中。

    

    命令的执行状态结果:

        成功:0,代表有执行过程顺利完成

        失败:1-255,代表执行过程中有错误发生,词法、语法分析出现问题?

    引用执行状态结果:$?


*什么是变量?

    某一事物运动过程中,数值可以变化的量。如炮弹飞行的速度就是变量。    

    变量单个命名的内存地址空间

    变量名内存空间的地址

    变量赋值:赋值符号后面的数据存储于变量名指向的内存空间

    变量的类型:本地变量、环境变量、特殊变量、局部变量    

    申明变量:    

        本地变量:var=value

        环境变量: export var=value,declare -i var=value

        特殊变量: $0,$1,..$#,$*,$@, \1,\2,\3

        局部变量: local var=value

    引用变量:既是引用变量名对应的内存空间中存储的数据


2)bash中的引用

    引用是修辞手法的一种,援用名人的话,或名人的事、物、诗文、典故、寓言成语俗语格言谚语等,引用前人千锤百炼的文字,或大家比较熟悉的名言,胜过自己用十倍篇幅所能表达言论的效果。

    linux中的引用不用考虑命令执行的过程以及命令如何实现,直接调用命令引用接口能完成一系列复杂的转换从而得到命令的执行结果变量中存储的值

  变量引用的方法: $VAR,${VAR}

  引用的类型:

        强引用:引用变量时,变量不会替换为变量中存储的值。

[root@izpo45bh60h6bsz ~]# echo '${PATH}'
${PATH}

        弱引用:引用变量时,会替换。 

[root@izpo45bh60h6bsz ~]# echo "${PATH}"
/usr/local/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

    

    命令执行结果的引用方法:

        `COMMAND`,$(COMMAND)

[root@izpo45bh60h6bsz ~]# pwd
/root
[root@izpo45bh60h6bsz ~]# echo `pwd`
/root
[root@izpo45bh60h6bsz ~]# echo $(pwd)
/root

3)bash的命令历史

    history命令

[root@izpo45bh60h6bsz ~]# type history
history is a shell builtin
[root@izpo45bh60h6bsz ~]# help history
history: history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]
    Display or manipulate the history list.

使用示例

1)显示命令历史

[root@izpo45bh60h6bsz ~]# history
    8  history
    9  cat /etc/fstab
   10  cat /etc/issue
   11  history

2)删除指定历史

[root@izpo45bh60h6bsz ~]# history -d 8
[root@izpo45bh60h6bsz ~]# history
    8  cat /etc/fstab
    9  cat /etc/issue
   10  history
   11  history -d 8
   12  history

3)清空所有历史

[root@izpo45bh60h6bsz ~]# history -c
[root@izpo45bh60h6bsz ~]# history
    8  history

4)将新记录的历史写入磁盘

[root@izpo45bh60h6bsz ~]# tail -1 .bash_history 
history | head 10
[root@izpo45bh60h6bsz ~]# history
    8  history
    9  tail -1 .bash_history 
   10  history
[root@izpo45bh60h6bsz ~]# history -a
[root@izpo45bh60h6bsz ~]# tail -1 .bash_history 
history -a
[root@izpo45bh60h6bsz ~]# tail  .bash_history 
history
cat .bash_history 
cat .bash_history 
cat .bash_history | wc -l
history
history | head 10
history
tail -1 .bash_history 
history
history -a

    命令历史的原理:

    登陆终端时,.bash_history中的历史条目会被自动加载至内存中。

    退出终端时,内存中的新生成的历史条目会被写入至磁盘中。

    

    HISTCONTROL变量控制命令记录的方式

    ignoredups  执行重复的命令,只会显示一次

[root@izpo45bh60h6bsz ~]# echo $HISTCONTROL
ignoredups               #重复的历史只显示一次

[root@izpo45bh60h6bsz ~]# 1
-bash: 1: command not found
[root@izpo45bh60h6bsz ~]# 1
-bash: 1: command not found
[root@izpo45bh60h6bsz ~]# 1
-bash: 1: command not found
[root@izpo45bh60h6bsz ~]# 1
-bash: 1: command not found
[root@izpo45bh60h6bsz ~]# history
   14  echo $HISTCONTROL
   15  1
   16  history

 ignorespaces:空白起始的命令不会记录至缓存命令中

[root@izpo45bh60h6bsz ~]# echo $HISTCONTROL
ignoredups               #重复的历史只显示一次
[root@izpo45bh60h6bsz ~]#  hello
-bash: /root/bin/hello: Permission denied
[root@izpo45bh60h6bsz ~]#  hello
-bash: /root/bin/hello: Permission denied
[root@izpo45bh60h6bsz ~]# history
   14  echo $HISTCONTROL
   17   hello       #空白行开始的行
   18  history
   
[root@izpo45bh60h6bsz ~]# echo $HISTCONTROL
ignorespace                #空白起始的命令不会记录
 [root@izpo45bh60h6bsz ~]#   hello
-bash: /root/bin/hello: Permission denied
[root@izpo45bh60h6bsz ~]#     hello
-bash: /root/bin/hello: Permission denied
[root@izpo45bh60h6bsz ~]#     hello
-bash: /root/bin/hello: Permission denied
[root@izpo45bh60h6bsz ~]# history
    19 echo $HISTCONTROL
    20 history

ignoreboth:同时满足以上两者

[root@izpo45bh60h6bsz ~]# export HISTCONTROL=ignoreboth
[root@izpo45bh60h6bsz ~]# echo $HISTCONTROL
ignoreboth
[root@izpo45bh60h6bsz ~]# cat /etc/fstab
[root@izpo45bh60h6bsz ~]# cat /etc/fstab
[root@izpo45bh60h6bsz ~]# cat /etc/fstab
[root@izpo45bh60h6bsz ~]# history
    8  export HISTCONTROL=ignoreboth
    9  echo $HISTCONTROL
   10  cat /etc/fstab
   11  history
 [root@izpo45bh60h6bsz ~]#   cat /etc/fstab
 [root@izpo45bh60h6bsz ~]#    cat /etc/fstab
 [root@izpo45bh60h6bsz ~]# history
    8  export HISTCONTROL=ignoreboth
    9  echo $HISTCONTROL
   10  cat /etc/fstab
   11  histroy
   12  history

HISTSIZE 历史的条目个数

[root@izpo45bh60h6bsz ~]# echo $HISTSIZE
1000

HISTFILE 当前用户历史记录文件

[root@izpo45bh60h6bsz ~]# echo $HISTFILE
/root/.bash_history

HISTFILESIZE 历史记录文件中的条目个数

[root@izpo45bh60h6bsz ~]# echo $HISTFILESIZE
1000

HISTTIMEFORMAT 给历史显示时间

[root@localhost ~]# history
  437  mkswap -U `uuidgen` /dev/sdb6
  438  mkswap -U `uuidgen` -L 'MYDATA' /dev/sdb6
  439  blkid /dev/sdb6
  440  hsitory
  441  history
  
[root@localhost ~]# declare -x HISTTIMEFORMAT='%F %T ' ##
  437  2017-08-08 00:27:58 mkswap -U `uuidgen` /dev/sdb6
  438  2017-08-08 00:28:18 mkswap -U `uuidgen` -L 'MYDATA' /dev/sdb6
  439  2017-08-08 00:28:34 blkid /dev/sdb6
  440  2017-08-08 01:31:46 hsitory
  441  2017-08-08 01:31:48 history
  442  2017-08-08 01:33:04 declare -x HISTTIMEFORMAT='%F %T '
  443  2017-08-08 01:33:05 history


调用命令历史的方法

    !# 重复执行第#条命令

    !! 重复执行上一条命令

    !string 执行最近一个以string开头的命令

    !$,ESC+. , ALT + . 仅调用上一次传递给命令的参数。 

4)bash中的通配符

    获取使用通配符的帮助手册

[root@izpo45bh60h6bsz ~]# man 7 glob

     通配符

    * 任意长度任意字符

[root@izpo45bh60h6bsz ~]# ls /etc/*.conf
/etc/asound.conf   /etc/host.conf    /etc/lftp.conf      ....

       ? 任意单个字符,??任意两个字符,????任意多个字符

[root@izpo45bh60h6bsz ~]# ls /etc/???.conf
/etc/ntp.conf  /etc/yum.conf
[root@izpo45bh60h6bsz ~]# ls /etc/????.conf
/etc/host.conf  /etc/krb5.conf  /etc/lftp.conf ...

    [] 匹配指定范围内的任意单个字符

  范围表示的方法:

    [pig] 表示p、i、g三个单词,中任意一个单词

[root@izpo45bh60h6bsz ~]# ls /etc/[mnpr]*.conf
/etc/man_db.conf  /etc/named.conf     /etc/nscd.conf      /etc/ntp.conf ...

    [a-z] 表示从a-z的任意一个字母,其中也包括所有大写字母

[root@izpo45bh60h6bsz ~]# ls p[a-z]*.conf
pabc.conf  pABC.conf  padc.conf  pADC.conf

    [A-Z] 所有大写字母

[root@izpo45bh60h6bsz ~]# ls p[A-Z]*.conf
pABC.conf  pADC.conf

    [0-9] 任意单个数字

[root@izpo45bh60h6bsz ~]# ls p[0-9]*.conf
p1ab.conf  p1AD.conf

    [^]匹配指定范围外的任意单个字符

[root@izpo45bh60h6bsz ~]# ls /etc/[^a-x]*.conf
/etc/yum.conf

            非多个范围时

[root@izpo45bh60h6bsz ~]# ls p[^A-Z0-9]*.conf
pabc.conf  padc.conf

字符集:

    [:digit:] 所有数字

    [:lower:] 所有小宝字母

    [:upper:] 所有大写字母

    [:alpha:] 所有字母

    [:alnum:] 字母和数字

    [:space:] 所有空白

    [:punct:] 所有特殊符号


    [[:space:]] 任意单个空白

    [[:alpha:]] 任意单个字母,相当于 [a-z]

    [[:digit:]] 任意单个数字,相当于 [0-9]


5)命令补全

    命令补全机制

        对于bash内置命令:bash自带

        外部命令: 先从hash表中查找,基于key键查找value,在缓存中查找的特性是查找所有缓存条目的时间是一致的,如果没有找到,再从当前用户的环境变量PATH中的路径从左而右的查找,第一次找到的即为本次要执行的命令,并且存入hash表中,以便下次查找。如果hash中缓存的条目失效了,即使PATH中变量能够找到对应的命令,也不会自动查找PATH中的变量,而是直接返回失效的结果,这时需要手动清空hash表。

[root@izpo45bh60h6bsz ~]# echo $PATH
/sbin:/usr/local/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@izpo45bh60h6bsz ~]# ls /
[root@izpo45bh60h6bsz ~]# ls /etc
[root@izpo45bh60h6bsz ~]# hash
hits	command
   2	/usr/bin/ls
[root@izpo45bh60h6bsz ~]# mv /usr/bin/ls /sbin/ls
[root@izpo45bh60h6bsz ~]# ls /
-bash: /usr/bin/ls: No such file or directory

[root@izpo45bh60h6bsz ~]# hash -r
[root@izpo45bh60h6bsz ~]# ls /
[root@izpo45bh60h6bsz ~]# hash
hits	command
   1	/sbin/ls

    命令补全的方法:

[root@izpo45bh60h6bsz ~]# cle + TAB键

        直接补全:用户给定的字符串只有一条惟一对应命令

[root@izpo45bh60h6bsz ~]# clear

    给出列表:用户给定的字符串有多个命令时,2次TAB给出命令列表

[root@izpo45bh60h6bsz ~]# ls + 2次TAB键
ls           lsattr       lsblk        lsb_release  lscpu        lsdiff       lsinitrd     lslocks      lslogins     lsmod        lspci        lsscsi
[root@izpo45bh60h6bsz ~]# ls

6)路径补全

    路径补全机制:把用户给出的字符串当做路径开头,并在给出的目录的上级目录下搜索指定的字符串开头的文件名。  

[root@izpo45bh60h6bsz ~]# ls /etc/sysconfig/netw + TAB键
[root@izpo45bh60h6bsz ~]# ls /etc/sysconfig/network

[root@izpo45bh60h6bsz ~]# ls /etc/sysconfig/net + 2次TAB键
netconsole       network          network-scripts/

7)命令行展开

    在命令执行的流程中,还有一个步骤:就是在命令 + Enter后,用户接口(shell程序)首先将,bash独有的特殊字符转换为另一种字符。例如:cd ~,回到当前用户的家目录,执行时,shell首先将cd ~命令的”~” 转换为当前用户的家目录”/home/username目录或者是/root目录”

    一些常用特殊字符的转换:

        1)~ 当前用户的家目录

[root@izpo45bh60h6bsz ~]# cd ~
[root@izpo45bh60h6bsz ~]# pwd
/root

        2)~Username username所对应用户的家目录

[root@izpo45bh60h6bsz ~]# cd ~tom
[root@izpo45bh60h6bsz tom]# pwd
/home/tom

        3){,,,} 承载一个以逗号分隔的列表,并以乘法结合律的规则分配。

[root@izpo45bh60h6bsz tom]# ls /etc/{fstab,issue}
/etc/fstab  /etc/issue

[root@izpo45bh60h6bsz tom]# mkdir {a,b}_{c,d}
[root@izpo45bh60h6bsz tom]# ls
a_c  a_d  b_c  b_d

8)bash中的I/O重定向

    用户键入命令的执行结果,都要输出至屏幕之上,可linux的哲学思想是“一切皆文件”,所以屏幕也被抽象为一个文件。linux中进程每打开一个文件都会有一个文件描述符(fd file description),跟踪打开的文件 

   程序的组成数据+指令算法+数据结构,程序都有读入数据的需求,执行结果输出的需求。

  1)数据存放位置?

    变量、数组、文件、列表

  2)输入时,默认从文件(键盘抽象的文件),从文件中读取数据,就要打开文件,其fd:0

    输出时,默认从文件(屏幕抽象的文件),标准输出为1,标准错误输出为2


  标准输出:执行状态结果为0

  标准错误输出:1-255,bash分析出语法错误,bash的结果

    

 重定向标准输出: command > position , command >> pos

    > 覆盖重定向,目标文件中的内容会被清除

[root@izpo45bh60h6bsz tom]# cat a.txt
a pig.
[root@izpo45bh60h6bsz tom]# echo '1' > a.txt 
[root@izpo45bh60h6bsz tom]# cat a.txt 
1

    >> 追加重定向,新内容会追加至文件尾部

[root@izpo45bh60h6bsz tom]# cat a.txt 
a pig.
[root@izpo45bh60h6bsz tom]# echo '1' >> a.txt 
[root@izpo45bh60h6bsz tom]# cat a.txt 
a pig.
1

    覆盖重定向: 

    set -C 禁止将内容覆盖输出至已有文件,仅对当前shell有效

不存在可以覆盖:

[root@izpo45bh60h6bsz tom]# ls
a_c  a_d  a.txt  b_c  b_d
[root@izpo45bh60h6bsz tom]# echo '1' > b.txt
[root@izpo45bh60h6bsz tom]# cat b.txt
1

存在覆盖会报错:

[root@izpo45bh60h6bsz tom]# cat a.txt 
a pig.
[root@izpo45bh60h6bsz tom]# echo '1' > a.txt 
-bash: a.txt: cannot overwrite existing file

    set +C 允许将内容覆盖输出至已有文件,仅对当前shell有效

    强制覆盖输出, COMAND >| POS

[root@izpo45bh60h6bsz tom]# set +C
[root@izpo45bh60h6bsz tom]# echo '1' > a.txt 
[root@izpo45bh60h6bsz tom]# cat a.txt
1

[root@izpo45bh60h6bsz tom]# set -C 
[root@izpo45bh60h6bsz tom]# echo '2' > a.txt 
-bash: a.txt: cannot overwrite existing file
[root@izpo45bh60h6bsz tom]# echo '2' >| a.txt  强制覆盖输出
[root@izpo45bh60h6bsz tom]# cat a.txt 
2


 重定向标错误输出: command 2> position , command 2>> pos

 重定向标错误输出和重定向标输出的差异:

[root@izpo45bh60h6bsz tom]# ls /var
[root@izpo45bh60h6bsz tom]# ls /var > /tmp/var.out
[root@izpo45bh60h6bsz tom]# cat /tmp/var.out

[root@izpo45bh60h6bsz tom]# ls /varr > /tmp/var.out #错误输出流,默认在屏幕上,没有重定向
ls: cannot access /varr: No such file or directory

 > 覆盖重定向,目标文件中的内容会被清除

[root@izpo45bh60h6bsz tom]# ls /varr 2> /tmp/var.out
[root@izpo45bh60h6bsz tom]# cat /tmp/var.out 
ls: cannot access /varr: No such file or directory

 >> 追加重定向,新内容会追加至文件尾部

[root@izpo45bh60h6bsz tom]# ls /rooter 2>> /tmp/var.out
[root@izpo45bh60h6bsz tom]# cat /tmp/var.out 
ls: cannot access /varr: No such file or directory
ls: cannot access /rooter: No such file or directory

标准输出和标准错误输出分别定向至不同的文件:

[root@izpo45bh60h6bsz tom]# ls /root > /tmp/var.out 2> /tmp/var.err
[root@izpo45bh60h6bsz tom]# ls /root >> /tmp/var.out 2>> /tmp/var.err

标准输出和标准错误输出分别定向至相同的文件:

[root@izpo45bh60h6bsz tom]# ls /root > /tmp/var.out 2> /tmp/var.out
[root@izpo45bh60h6bsz tom]# ls /root > /tmp/var.out 2>&1
[root@izpo45bh60h6bsz tom]# ls /root &> /tmp/var.out

   

输入重定向:<,<<

    一般用于不支持跟文件的命令,从标准输入读入数据

    cat,tr命令

[root@izpo45bh60h6bsz tom]# cat < /etc/fstab
[root@izpo45bh60h6bsz tom]# tr 'a-z' 'A-Z' <  /etc/fstab

    << 生成文档

        cat << EOF

        EOF

        cat > /path/to/somefie << EOF

        EOF

[root@izpo45bh60h6bsz ~]# cat << EOF
> hello
> world
> a
> pig
> .
> EOF
hello
world
a
pig
.
[root@izpo45bh60h6bsz ~]# cat > /tmp/test.out << EOF
> hello
> world
> a
> pig
> .
> EOF
[root@izpo45bh60h6bsz ~]# cat /tmp/test.out
hello
world
a
pig
.

9)bash的管道

    Linux的哲学思想之一 “组合众多小程序,完成复杂任务“的实现。

  实现机制:

    将前一个命令的标准输出作为后一个命令标准输入数据流

  表现形式:

    COMMAND1 | COMMAND2 | COMMAND3 | … …

    

    注意:最后一个命令是在当前shell进程的子shell进程中执行的

    例如:上一篇所用到的”echo aaaaaaaaaabbbbbbbbbbbcccccccdddd” | tr -s ‘adcb’

    此时,tr命令不用等待从标准输入读取数据,直接从前一个命令的标准输出作为后一个命令的标准输入

[root@izpo45bh60h6bsz ~]# ls /varr | tr 'a-z' 'A-Z' #标准错误输出不会被转换
ls: cannot access /varr: No such file or directory
[root@izpo45bh60h6bsz ~]# ls /var | tr 'a-z' 'A-Z'  #标准输出会被转换
ADM
CACHE
CRASH
DB
EMPTY

10)命令的别名

    别名,法定名符或规范的名称以外的名称,一种人、事、物、业在官方法定的名称之外还有另外的一种名称,或同是用之于书面,或同是用之于口语,有地方称之为昵称。 说的粗糙一点:男人除原配夫人外,保持情人关系的女人称“情妇”,别名“二奶”。

    别名的作用: 方便记忆、简化书写

   gnu/linux中如何定义别名 alias [-p] [name[=value] … ],定义即刻生效,仅对当前shell进程有效

[root@izpo45bh60h6bsz ~]# alias grep='grep -q'
[root@izpo45bh60h6bsz ~]# alias cdnet='cd /etc/sysconfig/network-scripts'
[root@izpo45bh60h6bsz ~]# cdnet
[root@izpo45bh60h6bsz network-scripts]# pwd
/etc/sysconfig/network-scripts

   显示当前系统上的所有别名 alias

[root@izpo45bh60h6bsz ~]# alias
alias cdweb='cd /etc/httpd'
alias cp='cp -i'
alias docker-ip='sudo docker inspect --format '\''{
   
   { .NetworkSettings.IPAddress }}'\'''

    撤销别名 

[root@izpo45bh60h6bsz network-scripts]# unalias cdnet
[root@izpo45bh60h6bsz network-scripts]# cdnet
-bash: cdnet: command not found

##撤销所有的别名
[root@izpo45bh60h6bsz ~]# alias
alias cdnet='cd /etc/sysconfig/network-scripts/'
alias cdweb='cd /etc/httpd'
alias cp='cp -i'
alias docker-ip='sudo docker inspect --format '\''{
   
   { .NetworkSettings.IPAddress }}'\'''
alias docker-pid='sudo docker inspect --format '\''``.`State`.`Pid`'\'''
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
[root@izpo45bh60h6bsz ~]# unalias -a
[root@izpo45bh60h6bsz ~]# alias ##没有显示任何别名了
[root@izpo45bh60h6bsz ~]#

  如果要想永久有效必须定义在配置文件中

[root@izpo45bh60h6bsz network-scripts]# vim ~/.bashrc
alias cdnet='cd /etc/sysconfig/network-scripts/'
[root@izpo45bh60h6bsz network-scripts]# cdnet #定义后不会立即生效
-bash: cdnet: command not found
[root@izpo45bh60h6bsz network-scripts]# . ~/.bashrc #重载配置文件即可生效
[root@izpo45bh60h6bsz network-scripts]# cdnet
[root@izpo45bh60h6bsz network-scripts]# pwd
/etc/sysconfig/network-scripts

让配置文件生效的方式

1、重启终端

2、source /path/to/config_ifle

3、. /path/to/config_ifle

快捷键

^c  强制取消命令执行

^d  正常终止命令

^uk 

^ae 行首或行尾

^l 清屏