框架:
bash的引用:命令引用、变量引用
bash命令历史
bash中的通配符
bash中的管道
I/O重定向
命令补全
路径补全
bash的快捷键
命令的别名
命令行的展开
1)命令的执行结果与命令的执行状态结果
命令的执行结果:
用户输入命令+Enter后,命令如何执行
命令提示符,回车键后:bash切片,分析命令,[选项],参数,提请给内核,分配资源,运行为一个进程
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,..$#,$*,[email protected], \1,\2,\3
局部变量: local var=value
引用变量:既是引用变量名对应的内存空间中存储的数据
2)bash中的引用
引用是修辞手法的一种,援用名人的话,或名人的事、物、诗文、典故、寓言、成语、俗语、格言、谚语等,引用前人千锤百炼的文字,或大家比较熟悉的名言,胜过自己用十倍篇幅所能表达言论的效果。
linux中的引用不用考虑命令执行的过程以及命令如何实现,直接调用命令引用接口能完成一系列复杂的转换从而得到命令的执行结果和变量中存储的值。
变量引用的方法: $VAR,${VAR}
引用的类型:
强引用:引用变量时,变量不会替换为变量中存储的值。
[[email protected] ~]# echo ‘${PATH}‘ ${PATH}
弱引用:引用变量时,会替换。
[[email protected] ~]# echo "${PATH}" /usr/local/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
命令执行结果的引用方法:
`COMMAND`,$(COMMAND)
[[email protected] ~]# pwd /root [[email protected] ~]# echo `pwd` /root [[email protected] ~]# echo $(pwd) /root
3)bash的命令历史
history命令
[[email protected] ~]# type history history is a shell builtin [[email protected] ~]# help history history: history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...] Display or manipulate the history list.
使用示例
1)显示命令历史
[[email protected] ~]# history 8 history 9 cat /etc/fstab 10 cat /etc/issue 11 history
2)删除指定历史
[[email protected] ~]# history -d 8 [[email protected] ~]# history 8 cat /etc/fstab 9 cat /etc/issue 10 history 11 history -d 8 12 history
3)清空所有历史
[[email protected] ~]# history -c [[email protected] ~]# history 8 history
4)将新记录的历史写入磁盘
[[email protected] ~]# tail -1 .bash_history history | head 10 [[email protected] ~]# history 8 history 9 tail -1 .bash_history 10 history [[email protected] ~]# history -a [[email protected] ~]# tail -1 .bash_history history -a [[email protected] ~]# 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 执行重复的命令,只会显示一次
[[email protected] ~]# echo $HISTCONTROL ignoredups #重复的历史只显示一次 [[email protected] ~]# 1 -bash: 1: command not found [[email protected] ~]# 1 -bash: 1: command not found [[email protected] ~]# 1 -bash: 1: command not found [[email protected] ~]# 1 -bash: 1: command not found [[email protected] ~]# history 14 echo $HISTCONTROL 15 1 16 history
ignorespaces:空白起始的命令不会记录至缓存命令中
[[email protected] ~]# echo $HISTCONTROL ignoredups #重复的历史只显示一次 [[email protected] ~]# hello -bash: /root/bin/hello: Permission denied [[email protected] ~]# hello -bash: /root/bin/hello: Permission denied [[email protected] ~]# history 14 echo $HISTCONTROL 17 hello #空白行开始的行 18 history [[email protected] ~]# echo $HISTCONTROL ignorespace #空白起始的命令不会记录 [[email protected] ~]# hello -bash: /root/bin/hello: Permission denied [[email protected] ~]# hello -bash: /root/bin/hello: Permission denied [[email protected] ~]# hello -bash: /root/bin/hello: Permission denied [[email protected] ~]# history 19 echo $HISTCONTROL 20 history
ignoreboth:同时满足以上两者
[[email protected] ~]# export HISTCONTROL=ignoreboth [[email protected] ~]# echo $HISTCONTROL ignoreboth [[email protected] ~]# cat /etc/fstab [[email protected] ~]# cat /etc/fstab [[email protected] ~]# cat /etc/fstab [[email protected] ~]# history 8 export HISTCONTROL=ignoreboth 9 echo $HISTCONTROL 10 cat /etc/fstab 11 history [[email protected] ~]# cat /etc/fstab [[email protected] ~]# cat /etc/fstab [[email protected] ~]# history 8 export HISTCONTROL=ignoreboth 9 echo $HISTCONTROL 10 cat /etc/fstab 11 histroy 12 history
HISTSIZE 历史的条目个数
[[email protected] ~]# echo $HISTSIZE 1000
HISTFILE 当前用户历史记录文件
[[email protected] ~]# echo $HISTFILE /root/.bash_history
HISTFILESIZE 历史记录文件中的条目个数
[[email protected] ~]# echo $HISTFILESIZE 1000
调用命令历史的方法
!# 重复执行第#条命令
!! 重复执行上一条命令
!string 执行最近一个以string开头的命令
!$,ESC+. , ALT + . 仅调用上一次传递给命令的参数。
4)bash中的通配符
获取使用通配符的帮助手册
[[email protected] ~]# man 7 glob
通配符
* 任意长度任意字符
[[email protected] ~]# ls /etc/*.conf /etc/asound.conf /etc/host.conf /etc/lftp.conf ....
? 任意单个字符,??任意两个字符,????任意多个字符
[[email protected] ~]# ls /etc/???.conf /etc/ntp.conf /etc/yum.conf [[email protected] ~]# ls /etc/????.conf /etc/host.conf /etc/krb5.conf /etc/lftp.conf ...
[] 匹配指定范围内的任意单个字符
范围表示的方法:
[pig] 表示p、i、g三个单词,中任意一个单词
[[email protected] ~]# ls /etc/[mnpr]*.conf /etc/man_db.conf /etc/named.conf /etc/nscd.conf /etc/ntp.conf ...
[a-z] 表示从a-z的任意一个字母,其中也包括所有大写字母
[[email protected] ~]# ls p[a-z]*.conf pabc.conf pABC.conf padc.conf pADC.conf
[A-Z] 所有大写字母
[[email protected] ~]# ls p[A-Z]*.conf pABC.conf pADC.conf
[0-9] 任意单个数字
[[email protected] ~]# ls p[0-9]*.conf p1ab.conf p1AD.conf
[^]匹配指定范围外的任意单个字符
[[email protected] ~]# ls /etc/[^a-x]*.conf /etc/yum.conf
非多个范围时
[[email protected] ~]# 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表。
[[email protected] ~]# echo $PATH /sbin:/usr/local/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin [[email protected] ~]# ls / [[email protected] ~]# ls /etc [[email protected] ~]# hash hits command 2 /usr/bin/ls [[email protected] ~]# mv /usr/bin/ls /sbin/ls [[email protected] ~]# ls / -bash: /usr/bin/ls: No such file or directory [[email protected] ~]# hash -r [[email protected] ~]# ls / [[email protected] ~]# hash hits command 1 /sbin/ls
命令补全的方法:
[[email protected] ~]# cle + TAB键
直接补全:用户给定的字符串只有一条惟一对应命令
[[email protected] ~]# clear
给出列表:用户给定的字符串有多个命令时,2次TAB给出命令列表
[[email protected] ~]# ls + 2次TAB键 ls lsattr lsblk lsb_release lscpu lsdiff lsinitrd lslocks lslogins lsmod lspci lsscsi [[email protected] ~]# ls
6)路径补全
路径补全机制:把用户给出的字符串当做路径开头,并在给出的目录的上级目录下搜索指定的字符串开头的文件名。
[[email protected] ~]# ls /etc/sysconfig/netw + TAB键 [[email protected] ~]# ls /etc/sysconfig/network [[email protected] ~]# ls /etc/sysconfig/net + 2次TAB键 netconsole network network-scripts/
7)命令行展开
在命令执行的流程中,还有一个步骤:就是在命令 + Enter后,用户接口(shell程序)首先将,bash独有的特殊字符转换为另一种字符。例如:cd ~,回到当前用户的家目录,执行时,shell首先将cd ~命令的"~" 转换为当前用户的家目录"/home/username目录或者是/root目录"
一些常用特殊字符的转换:
1)~ 当前用户的家目录
[[email protected] ~]# cd ~ [[email protected] ~]# pwd /root
2)~Username username所对应用户的家目录
[[email protected] ~]# cd ~tom [[email protected] tom]# pwd /home/tom
3){,,,} 承载一个以逗号分隔的列表,并以乘法结合律的规则分配。
[[email protected] tom]# ls /etc/{fstab,issue} /etc/fstab /etc/issue [[email protected] tom]# mkdir {a,b}_{c,d} [[email protected] 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
> 覆盖重定向,目标文件中的内容会被清除
[[email protected] tom]# cat a.txt a pig. [[email protected] tom]# echo ‘1‘ > a.txt [[email protected] tom]# cat a.txt 1
>> 追加重定向,新内容会追加至文件尾部
[[email protected] tom]# cat a.txt a pig. [[email protected] tom]# echo ‘1‘ >> a.txt [[email protected] tom]# cat a.txt a pig. 1
覆盖重定向:
set -C 禁止将内容覆盖输出至已有文件,仅对当前shell有效
不存在可以覆盖:
[[email protected] tom]# ls a_c a_d a.txt b_c b_d [[email protected] tom]# echo ‘1‘ > b.txt [[email protected] tom]# cat b.txt 1
存在覆盖会报错:
[[email protected] tom]# cat a.txt a pig. [[email protected] tom]# echo ‘1‘ > a.txt -bash: a.txt: cannot overwrite existing file
set +C 允许将内容覆盖输出至已有文件,仅对当前shell有效
强制覆盖输出, COMAND >| POS
[[email protected] tom]# set +C [[email protected] tom]# echo ‘1‘ > a.txt [[email protected] tom]# cat a.txt 1 [[email protected] tom]# set -C [[email protected] tom]# echo ‘2‘ > a.txt -bash: a.txt: cannot overwrite existing file [[email protected] tom]# echo ‘2‘ >| a.txt 强制覆盖输出 [[email protected] tom]# cat a.txt 2
重定向标错误输出: command 2> position , command 2>> pos
重定向标错误输出和重定向标输出的差异:
[[email protected] tom]# ls /var [[email protected] tom]# ls /var > /tmp/var.out [[email protected] tom]# cat /tmp/var.out [[email protected] tom]# ls /varr > /tmp/var.out #错误输出流,默认在屏幕上,没有重定向 ls: cannot access /varr: No such file or directory
> 覆盖重定向,目标文件中的内容会被清除
[[email protected] tom]# ls /varr 2> /tmp/var.out [[email protected] tom]# cat /tmp/var.out ls: cannot access /varr: No such file or directory
>> 追加重定向,新内容会追加至文件尾部
[[email protected] tom]# ls /rooter 2>> /tmp/var.out [[email protected] tom]# cat /tmp/var.out ls: cannot access /varr: No such file or directory ls: cannot access /rooter: No such file or directory
标准输出和标准错误输出分别定向至不同的文件:
[[email protected] tom]# ls /root > /tmp/var.out 2> /tmp/var.err [[email protected] tom]# ls /root >> /tmp/var.out 2>> /tmp/var.err
标准输出和标准错误输出分别定向至相同的文件:
[[email protected] tom]# ls /root > /tmp/var.out 2> /tmp/var.out [[email protected] tom]# ls /root > /tmp/var.out 2> &1 [[email protected] tom]# ls /root &> /tmp/var.out
输入重定向:<,<<
一般用于不支持跟文件的命令,从标准输入读入数据
cat,tr命令
[[email protected] tom]# cat < /etc/fstab [[email protected] tom]# tr ‘a-z‘ ‘A-Z‘ < /etc/fstab
<< 生成文档
cat << EOF
EOF
cat > /path/to/somefie << EOF
EOF
[[email protected] ~]# cat << EOF > hello > world > a > pig > . > EOF hello world a pig . [[email protected] ~]# cat > /tmp/test.out << EOF > hello > world > a > pig > . > EOF [[email protected] ~]# cat /tmp/test.out hello world a pig .
9)bash的管道
Linux的哲学思想之一 "组合众多小程序,完成复杂任务"的实现。
实现机制:
将前一个命令的标准输出作为后一个命令标准输入数据流
表现形式:
COMMAND1 | COMMAND2 | COMMAND3 | ... ...
注意:最后一个命令是在当前shell进程的子shell进程中执行的
例如:上一篇所用到的"echo aaaaaaaaaabbbbbbbbbbbcccccccdddd" | tr -s ‘adcb‘
此时,tr命令不用等待从标准输入读取数据,直接从前一个命令的标准输出作为后一个命令的标准输入
[[email protected] ~]# ls /varr | tr ‘a-z‘ ‘A-Z‘ #标准错误输出不会被转换 ls: cannot access /varr: No such file or directory [[email protected] ~]# ls /var | tr ‘a-z‘ ‘A-Z‘ #标准输出会被转换 ADM CACHE CRASH DB EMPTY
10)命令的别名
别名,法定名符或规范的名称以外的名称,一种人、事、物、业在官方法定的名称之外还有另外的一种名称,或同是用之于书面,或同是用之于口语,有地方称之为昵称。 说的粗糙一点:男人除原配夫人外,保持情人关系的女人称“情妇”,别名“二奶”。
别名的作用: 方便记忆、简化书写
gnu/linux中如何定义别名 alias [-p] [name[=value] ... ],定义即刻生效,仅对当前shell进程有效
[[email protected] ~]# alias grep=‘grep -q‘ [[email protected] ~]# alias cdnet=‘cd /etc/sysconfig/network-scripts‘ [[email protected] ~]# cdnet [[email protected] network-scripts]# pwd /etc/sysconfig/network-scripts
显示当前系统上的所有别名 alias
[[email protected] ~]# alias alias cdweb=‘cd /etc/httpd‘ alias cp=‘cp -i‘ alias docker-ip=‘sudo docker inspect --format ‘\‘‘{{ .NetworkSettings.IPAddress }}‘\‘‘‘
撤销别名
[[email protected] network-scripts]# unalias cdnet [[email protected] network-scripts]# cdnet -bash: cdnet: command not found
如果要想永久有效必须定义在配置文件中
[[email protected] network-scripts]# vim ~/.bashrc alias cdnet=‘cd /etc/sysconfig/network-scripts/‘ [[email protected] network-scripts]# cdnet #定义后不会立即生效 -bash: cdnet: command not found [[email protected] network-scripts]# . ~/.bashrc #重载配置文件即可生效 [[email protected] network-scripts]# cdnet [[email protected] network-scripts]# pwd /etc/sysconfig/network-scripts
让配置文件生效的方式
1、重启终端
2、source /path/to/config_ifle
3、. /path/to/config_ifle