bash 特性

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 防止扩展的两种方式

  1. 转义:加反斜线(\) 使之成为普通字符

    [root@CentOS8 ~]# echo cost:$5.00   #系统默认$5是一个变量,输出无法达到预计效果
    cost:.00
    [root@CentOS8 ~]# echo cost:\$5.00  #加\之后转义为普通字符,即可正常显示
    cost:$5.00
    
  2. 加引号来防止扩展

    正向单引号 ‘ ’ 双引号 “ ” 反向单引号 ``
    一律按普通字符处理 只支持变量 支持命令、支持变量
    #引号的功能区分
    [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开头的命令的相关参数

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。