5 bash shell特性
5.1 命令行扩展
功能:把命令行中输入的特殊字符 自动替换为 相应的字符串
5.1.1 家目录
- ~ 表示当前用户家目录
- ~username 表示指定用户家目录
5.1.2 执行结果引用:$( )
功能:把一个命令的输出结果 作为另一个命令的参数
$(CMD) 或 `CMD`(反单引号)
使用举例:
[root@CentOS8 data]#echo "this system's name is $(hostname)"
this system's name is CentOS8.jacklee
[root@CentOS8 data]#echo "caokunzi is `whoami`"
caokunzi is root
[root@CentOS8 data]#touch $(date +%F).log
[root@CentOS8 data]#ll
total 0
-rw-r--r--. 1 root root 0 Jul 3 10:33 2020-07-03.log
5.1.3 括号扩展:{ }
实现打印重复字符串的简化形式(按照ASCII码,顺序或倒序排列均可)
简单应用:
[root@CentOS8 data]#echo zhubazi{1,5,9}
zhubazi1 zhubazi5 zhubazi9
[root@CentOS8~]#echo a{d,g,j}c
adc agc ajc
[root@CentOS8 data]#echo {1..5}
1 2 3 4 5
[root@CentOS8 data]#echo {a..d}
a b c d
[root@CentOS8 data]#echo {b..X}
b a ` _ ^ ] [ Z Y X
[root@CentOS8 data]#echo {A..z}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@CentOS8 data]#echo {00..10}
00 01 02 03 04 05 06 07 08 09 10
[root@CentOS8 data]#echo {1..10..2}
1 3 5 7 9
[root@CentOS8 data]#echo {20..1..3}
20 17 14 11 8 5 2
[root@CentOS8~]#echo {a..h..2} #字母也可以等差排列!!!
a c e g
高级应用:
[09:59:47root@CentOS8~]#mkdir -p /data/{a,b,c}/
[10:00:39root@CentOS8~]#tree /data/
/data/
├── a
├── b
└── c
[10:03:04root@CentOS8~]#mkdir -p /data/{a,b}/{x,y}
[10:03:11root@CentOS8~]#tree /data/
/data/
├── a
│ ├── x
│ └── y
└── b
├── x
└── y
{ }的扩展功能可关闭
echo $-
[10:07:36jack@ubuntu1804~]$ echo $-
himBHs #每个字母表示一种功能
#其中B控制扩展
set +B 取消扩展功能
[21:32:14root@CentOS8/~]# echo {1..5}
1 2 3 4 5
[21:32:16root@CentOS8/~]# set +B
[21:32:26root@CentOS8/~]# echo {1..5}
{1..5}
[21:32:28root@CentOS8/~]# set -B
[21:32:40root@CentOS8/~]# echo {1..5}
1 2 3 4 5
5.1.4 防止扩展的两种方式
-
转义:加反斜线(\) 使之成为普通字符
[root@CentOS8 ~]# echo cost:$5.00 #系统默认$5是一个变量,输出无法达到预计效果 cost:.00 [root@CentOS8 ~]# echo cost:\$5.00 #加\之后转义为普通字符,即可正常显示 cost:$5.00
-
加引号来防止扩展
正向单引号 ‘ ’ 双引号 “ ” 反向单引号 `` 一律按普通字符处理 只支持变量 支持命令、支持变量 #引号的功能区分 [root@CentOS8 ~]# echo 'echo $USER' #单引六亲不认 echo $USER [root@CentOS8 ~]# echo "echo $USER" #双引只认变量 echo root [root@CentOS8 ~]# echo `echo $USER` #反向全部生效 root
5.2 通配符 glob
功能:对相关文件名进行匹配,实现快速引用多个文件
* 匹配零个或多个字符
? 匹配任意#单个字符
~ 当前用户家目录
~jack 用户jack的家目录
~- 上一个工作目录
中括号[ ]匹配指定集合内任意单个字符 #单个!!!!!!!!
[[:digit:]] 匹配单个数字
[[:lower:]] 匹配单个小写字母
[[:upper:]] 匹配单个大写字母
[[:alpha:]] 任意单个字母
[[:alnum:]] 任意单个数字或字母
[[:blank:]] #空格和Tab
[[:space:]] #任意单个空白字符(包括但不限于空格和Tab)
[[:punct:]] 任意单个标点
[[:print:]] 可打印的'所有字符
[[:graph:]] 可打印的'图形字符
[[:cntrl:]] 非打印字符
[jack] 匹配列表中的任何的一个字符,j/a/c/k任何一个
[^jack] 匹配 除了j/a/c/k之外的 任何一个 # ^表示取反!!!
5.3 变量
变量的功能:
- 在程序中多次引用,修改变量即可达到全局修改效果,提升效率
- 将一个非常长的字符串赋值给一个短小变量名,方便使用
5.3.1 变量赋值和引用
在bash中使用变量,需要先进行定义(赋值)
#变量名=变量对应的值
如 NAME=jacklee #等号的前后不能有空格!!!!!!!!!!
#引用变量使用 $变量名
echo $NAME
#删除自定义变量
unset NAME
使用变量需要遵守的规则:
变量名只允许包含英文字母、数字、下划线,而且不能以数字开头
变量名避免使用shell中的命令和关键字,如 id 、do
-
变量值包括空格时,应该使用引号括起来,如 ‘ ’ ” “
[11:49:31root@CentOS8~]#VAR=zhu bazi bash: bazi: command not found... Failed to search for file: Cannot update read-only repo [14:02:54root@CentOS8~]#VAR='zhu bazi' [14:03:06root@CentOS8~]#echo $VAR zhu bazi
-
转义符(\):可取消特殊字符的功能,视为普通字符处理
[14:03:16root@CentOS8~]#PAY=$100 [14:03:51root@CentOS8~]#echo $PAY 00 [14:04:04root@CentOS8~]#PAY=\$100 [14:04:10root@CentOS8~]#echo $PAY $100
若变量未赋值直接引用,其值为空,即null,不是空格!!!
-
引用变量时,若变量名和其他字符相连,需要使用格式 ${变量名}
[14:04:12root@CentOS8~]#NAME=jack [14:09:40root@CentOS8~]#echo $NAME$PAY #两个变量紧挨着,正常引用 jack$100 [14:10:40root@CentOS8~]#echo $NAME_$PAY #两变量之间有下划线,前者信息丢失!!! $100 [14:12:03root@CentOS8~]#echo ${NAME}_$PAY #两个变量相连,前者需要加花括号{} jack_$100 [14:12:33root@CentOS8~]#echo ${NAME}_$PAY_$VAR jack_zhu bazi [14:15:48root@CentOS8~]#echo ${NAME}_${PAY}_$VAR #多个变量,只有最后一个不用加 jack_$100_zhu bazi
5.3.2 变量的分类
bash中的变量基本分类:
- 内置:bash中自带的变量
- 自定义:用户根据自身需要实现的
按作用范围分类:
普通变量——作用于当前shell进程
shell进程终止则变量自动撤销-
环境变量——作用于当前shell进程以及其子进程
使用bash命令可开启新的子shell,pstree可查看详情
在子shell中用unset删除自定义环境变量,父shell中不会失效
需要使用export或declare -x来声明 才可成为环境变量 #声明环境变量 export name=VALUE declare -x name=VALUE #显示所有环境变量相关的命令 env export declare -x
-
本地变量——作用于可引用到的范围,比如函数
需要使用local来声明 #声明本地变量 local 变量名 #显示所有变量和函数!!!!!!!! set
按是否可修改分类
可修改变量
-
只读变量(需要用户自己声明)
#声明只读变量格式: readonly 变量名 #显示所有只读变量相关命令 readonly declare -r
只读变量声明后不可用unset删除
[14:40:43root@CentOS8~]#readonly PI [14:40:49root@CentOS8~]#PI=3.14159 -bash: PI: readonly variable [14:41:00root@CentOS8~]#unset PI -bash: unset: PI: cannot unset: readonly variable
5.3.3 常见的系统内置变量
存在一些特殊的变量,实现shell的特定功能
UID: 当前用户的UID
HOME: 当前用户的家目录
SHELL: 当前使用的shell类型 /bin/bash
BASHPID: 当前bash的进程编号
HISTSIZE: 缓冲区记录命令历史的数量
MAIL: 当前用户的邮件信息储存目录 /var/spool/mail/root
PATH: 二进制执行文件(外部命令)的搜索路径
LANG: 系统使用的语言和编码字符集 en_US.UTF-8
RANDOM: 生成随机数,0~32767
PS1: 命令提示符
OSTYPE: 操作系统类型 linux-gnu
HOSTTYPE: 主机类型 x86_64
MACHTYPE: 机器类型 x86_64-redhat-linux-gnu
5.3.4 执行状态结果变量
每个命令执行完毕都会生成一个状态码,称为执行状态结果,不直接在屏幕显示
echo $? 输出状态码
=0 表示上个命令执行成功
=1~255表示出现错误
[15:01:05root@CentOS8data]#ll a
total 0
drwxr-xr-x 2 root root 6 Jul 25 10:03 x
drwxr-xr-x 2 root root 6 Jul 25 10:03 y
[15:01:14root@CentOS8data]#echo $?
0
[15:01:20root@CentOS8data]#ll c
ls: cannot access 'c': No such file or directory
[15:01:25root@CentOS8data]#echo $?
2
5.4 变量中使用引号
正向单引号 ‘ ’ | 双引号 “ ” | 反向单引号 `` |
---|---|---|
一律按普通字符处理 | 只支持变量 | 支持命令、支持变量 |
大傻 | 二傻 | 与 $( ) 功能相同 |
[root@CentOS8 ~]# echo 'echo $USER'
echo $USER
[root@CentOS8 ~]# echo "echo $USER"
echo root
[root@CentOS8 ~]# echo `echo $USER`
root
[root@CentOS8data]#echo $(echo $USER)
root
因此反单引号与 $( ) 经常用于 命令输出结果被另一个命令引用的情形
5.5 同时执行多个命令
5.5.1 分号连接
用分号按顺序连接即可
cmd1;cmd2;cmd3...
[15:52:07root@CentOS8data]#ls;echo $LANG;cat /etc/issue
a b
en_US.UTF-8
\S
Kernel \r on an \m
5.5.2 括号 ( ) 和 { }
(cmd1;cmd2;cmd3...)
{ cmd1;cmd2;cmd3...cmdN; } #前方需要加空格!!!
需要注意
- 使用()会开启子shell,在()内部的变量赋值不会影响当前shell中的变量值
- 开头{ 与第一个命令之间至少要有一个空格,最后一个命令必须以 ;结束
试比较以下两种命令的输出结果:
[root@centos8 ~]#name=mage;(echo $name;name=wang;echo $name );echo $name
mage
wang #由于开启了子shell,后续name的值仍然是mage
mage
[root@centos8 ~]#name=mage;{ echo $name;name=wang;echo $name; } ;echo $name
mage
wang
wang #未开启子shell,因此name赋值已经改变
5.6 命令行历史与其调用
5.6.1 命令历史
使用bash shell过程中,执行过的命令会被记录到history的缓冲区,当用户注销时,缓冲区中的命令历史会被追加保存到/.bash_history文件中,再次登录shell时,会读取命令历史文件中记录下的命令/.bash_history
登录进shell后新执行的命令会继续记录在缓存中,用户退出时再追加至上述文件储存
因此退出重新登录即可将刚刚执行的命令写入历史文件中
5.6.2 history命令
history命令可以显示和管理曾经执行过的命令
history [-c] 或 [-d offset] [n]
-c: 清空缓冲区的所有历史命令#只对缓冲区
-d offset: 删除历史中指定的#第n个命令
history -anrw [filename]
-a: 将历史命令缓冲区中的命令写入历史命令文件中 #保存缓冲区内容
-n: 读历史文件中未读过的行到历史列表
-r: 将历史命令文件中的命令读取到当前历史命令缓冲区#填充缓冲区
-w: 保存命令历史列表到指定的历史文件
history -ps arg [arg...]
-p: 展开历史参数成多行,但不存在历史列表中
-s: 展开历史参数成一行,附加在历史列表后
N: 显示最近的n条历史
想要彻底删除所有历史,先删除磁盘.bash_history,再清空缓存,操作如下:
[root@CentOS8 data]#rm -f .bash_history
[root@CentOS8 data]#history -c
5.6.3 命令历史相关环境变量
HISTSIZE:命令历史缓冲区记录的条数
HISTFILE:指定历史文件,默认为~/.bash_history
HISTFILESIZE:命令历史文件记录的条数
HISTTIMEFORMAT="%F %T " 在历史记录中显示命令执行的时间
HISTIGNORE="str1:str2:…" 忽略以str1与str2开头*的命令的历史
HISTCONTROL:控制命令历史的记录方式,可选项如下:
- ignoredups 是默认值,忽略重复的命令,认为连续且相同为“重复”
- ignorespace 忽略所有以空白开头的命令
- ignoreboth = ignoredups + ignorespace
- erasedups 删除重复命令
修改后持久保存:
输入内容:export 变量名="值"
存放在 /etc/profile 或 ~/.bash_profile
同理,编辑之后不会立即生效,运行 . .bash_profile
5.6.4 调用命令行历史
1===重复前一个命令的几种方式:
- 使用上方向键,并回车执行
- 输入 !! 并回车执行
- 输入 !-1 并回车执行
- 按 Ctrl+p 并回车执行
- ! n 执行历史中第n个命令
- ! -n 执行历史中倒数第n个命令
- ! : 0 执行上一个不包含参数的命令
2===命令关键字xxx
重复#上一个以xxx开头的命令:!xxx
重复#上一个包含xxx的命令:! ? xxx
3===打印输出但不执行 : p
!xxx:p 打印输出#上一个以xxx开头的命令
!$:p 打印输出上一个命令的#最后一个参数
!*:p 打印输出上一个命令的#全部参数
4===调用上一个命令的 最后一个参数
- !$
- 快捷键 esc , . (先后按)
- 快捷键 Alt + . (同时按) #若不起作用,需要设置Xshell终端>键盘
5===在命令历史中搜索
- Ctrl + r 开始搜索
- Ctrl + g 退出搜索
6===调用上一个命令的指定参数
cmd !^ 调用上个命令第一个arg
cmd !$ 调用上个命令最后一个arg
cmd !* 调用上个命令#全部arg
cmd !:n 调用#第n个arg
- cmd ! n: 再配合上式表示调用第n条命令的相关参数
- cmd ! xxx: 再配合上式表示调用上个以xxx开头的命令的相关参数