2、shell

2.1、shell基础正则表达式

​ 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。并规定一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是正则表达式( Regular Expression ) 。

2.1.1、普通元字符

字符 描述
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。串行“\\”匹配“\”而“\(”则匹配“(”。
^ 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo能匹配“z”以及“zoo”。等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。
{n} n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{n,} n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
{n,m} mn均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,*m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
. 匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“(.|\n)”的模式。
x|y 匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。
[xyz] 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
[^xyz] 负值字符集合。匹配未包含的任意字符例如,"[^abc]"可以匹配“ plain ”中的“ plin ”
[a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
\B 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
\cx 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。
\d 匹配一个数字字符。等价于[0-9]。
\D 匹配一个非数字字符。等价于[^0-9]。
\f 匹配一个换页符。等价于\x0c和\cL。
\n 匹配一个换行符。等价于\x0a和\cJ。
\r 匹配一个回车符。等价于\x0d和\cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于[^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于\x09和\cI。
\v 匹配一个垂直制表符。等价于\x0b和\cK。
\w 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。
\W 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
| 将两个匹配条件进行逻辑“或”运算。例如正则表达式(himl her)匹配” it belongs to him”和”It belongs to her”,但是不能匹配”it belongs to them"
() 将部分内容合成一个单元组。例如,要搜索glad 或good ,可以采用’g(laloo)d’这种方式。()的好处是可以对小组使用+、?、*等

例如 取出一个IP地址:~]# echo '192.168.1.1' | grep -E --color "([0-9]{1,3}\.){3}[0-9]{1,3}"

2.1.2、shell特殊字符

名称 字符 实际作用
双引号 " 用来使shell 无法认出除字符$、‘ 、飞外的任何字符或字符串,也称之为弱引用
单引号 用来使shell 无法认出所有特殊字符,也称之为强引用
反引号 ` 用来特换命令,将当前命令优先执行
分号 ; 允许在一行放多个命令
& 后台执行,建议带上nohup
大括号 {} 创建命令块
字符集合 <>& 重定向
字符集合 * ? [] ! 表示模式匹配
$ 变量名的开头
# 注释,第一行魔数除外

2.1.3、变量和运算符

变量是放置在内存中的一定的存储单元,这个存储单元里存放的是这个单元的值,这个值是可以改变的,我们称之为变量。

变量名=”变量”
readonly 变量名=”变量”设置该变量为只读变量,则这个变量不能被改变。
echo $变量名
set 显示本地所有的变量
unset 变量名清除变量
readonly 显示当前shell 下有哪些只读变量

2.1.3.1、特殊变量

符号 作用
$0 当前脚本的名称
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。
例如,第一个参数是\$1,第二个参数是$2。
$# 表示位置参数的总数
$* 传递给脚本或函数的所有参数
$@ 传递给脚本或函数的所有参数。被双引号""包含时,与 $* 稍有不同
$? 上个命令的退出状态,或函数的返回值。
$$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

2.1.3.2、示例

# 位置参数脚本  $n
]# cat location.sh 
    #!/bin/bash
    #
    echo "第一个参数: " $1
    echo "第二个参数: " $2
    echo "第三个参数: " $3
    echo "第四个参数: " $4

]# bash location.sh 1 2 3 
    第一个参数:  1
    第二个参数:  2
    第三个参数:  3
    第四个参数:     # 如果不传就是空
#    $# $@
]# cat shift.sh 
    #!/bin/bash
    #
    echo "总数: $#"     # 获取传递参数的总数
    echo "@: $@"       # 获取传递参数的所有值
    echo "@: "$*       # 获取传递参数的所有值

]# bash shift.sh 192.168.1.1 192.168.1.2 192.168.1.3
    总数: 3
    @: 192.168.1.1 192.168.1.2 192.168.1.3

*\$@ 与 $ 的区别?**

  • \$@ 和 \$* 都表示脚本或者函数传入的参数,不被双引号""包含时,都以 \$1 ​\$2 … \$n 的形式输出所有参数,
  • 但是当它们被双引号 “” 包含时,
    • "\$*" 会将所有的参数作为一个整体,以"\$1 \$2 … \$n"的形式输出所有参数。
    • "\$@" 会将各个参数分开,以的$1 \$2 … \$n形式输出所有参数

2.1.3.3、调试shell脚本

1、脚本中加上
    set -x  # 打印过程
    set +x  # 只打印部分过程

2、直接使用   bash -x script.sh 

2.1.4、退出\变量

退出: 可以利用 exit[n] ,n必须是0-255范围的整数,$?内部变量可以执行最后一条命令的退出状态, 0为true, 其它数值皆为errors

变量:Shell 变量名可以由字母、数字和下划线等字符组成,但第一个字符必须是字母或下划线

变量可以分为内部变量、本地变量、环境变量、参数变量和用户定义的变量, 以下为它们的定义:

  • 内部变量:为了便于Shell 编程而由Shell 设定的变量。如错误类型的ERRNO 变量。
  • 本地变量:在代码块或函数中定义的变量,且仅在定义的范围内有效。
  • 参数变量:调用Shell 脚本或函数时传递的变量。
  • 环境变量:为系统内核、系统命令和用户命令提供运行环境而设定的变量。
  • 用户变量:为运行用户程序或完成某种特定任务而设定的普通变量或临时变量。

ps: 在赋值时 x=123, 等于号两边不能有空格,shell语法限定

2.1.4.1、内部变量

变量名 作用
PWD 表示当前的工作目录, 其变量值等同于pwd 内部命令的输出
RANDOM 每次引用这个变量时都会生成一个均匀分布的0 ~ 32767 范围内的随机整数
SCONDS 脚本已经运行的时间(单位:秒)
PPID 当前进程的父进程的进程ID
$? 表示最近一次执行的命令或shell 脚本的出口状态

2.1.4.2、环境变量

变量名 作用
EDITOR 用于确定命令行编辑所用的编辑程序,通常为vim
HOME 用户主目录
PATH 指定命令的检索路径
# 将程序的执行文件加入到系统默认环境变量中,如 java
]# cat /etc/profile.d/java.sh 
    export JAVA_HOME=/usr/java/jdk
    export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    export PATH=$PATH:$JAVA_HOME/bin

]# source !$  然后env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/java/jdk/bin:/root/bin:/usr/java/jdk/bin   # 加入的默认 PATH
PWD=/root/testBash/231  # 当前的环境变量
JAVA_HOME=/usr/java/jdk  # JAVA_HOME 路径

系统环境变量文件(重要)

配置文件读取: /etc/profile -->/etc/profile.d/*.sh -->~/.bash_profile-->~/.bashrc -->/etc/bashrc

  1. /etc/profile: 全局,当前系统上所有用户都可以读取到环境变量
  2. $HOME/.bash__profile: 当前用户的环境变量,只局限于当前这个用户

2.1.4.3、变量引用

引用变量的两种形式: \$variable 与\$ {variable }

2.1.5、部分常用命令介绍

参考文档-1 参考文档-2

2.1.5.1、冒号

​ 与true 语句不执行任何实际的处理动作,但可用于返回一个出口状态为0 的测试条件。这两个语句常用于While 循环结构的元限循环测试条件,我们在脚本中经常会见到这样的使用:

while :   # 这表示是一个无限循环的过程,所以使用的时候要特别注意,不要形成了死循环,所以一般会定义一个sleep 时间,可以实现秒级别的cron 任务,其语法格式为:

# ; 分号允许在一行放多个命令
while :;do echo 'yep'; sleep 3;done  # 实例了一个无限循环,每隔3秒打印一次yep

2.1.5.2、echo 与print 命令

# 显示各种信息,主要用于跟awk配合,输出截取的字段详细信息如:
    ]# ps aux | grep jdk | grep -v "grep"  | awk '{print $2}'

2.1.5.3、read

​ read 语句的主要功能是读取标准输入的数据,然后存储到变量参数中, 交互式标准输入,

]# cat read.sh 
#!/bin/bash
#
read -p "请输入参数: " variable    # 带上提示符输出, bash script.sh
echo ${variable}

默认值demo

# 倒计时,如果在5秒内没有输入任何字符,则使用字定义的value
]# cat read2.sh 
#!/bin/bash
#
read -p "倒计时测试: " -t 5 variable2
va="test"
variable2=${variable2:-$va}
echo $variable2

2.1.5.4、set 与unset

  1. set: set 命令用于修改或重新设置位置参数的值。set --用于清除所有位置参数
  2. unset: 删除位置变量 如 a="hello" unset a 就清除了

2.1.5.5、expr 算术运算

符号 作用 示例
+ 加法 a=10;b=20;expr $a + $b结果为 30。注意空格
- 减法 expr $a - $b 结果为-10
* 乘法 expr $a * $b 结果为200
/ 除法 expr $b / $a 结果为2
% 取余 expr $b % $a 结果为 0
= 赋值 a=$b,将把变量 b 的值赋给 a
(()) 双小括号算术运算符,用于 替代expr 命令 for((i=0;i<10;++i))或者((out=$a*$b))或者if(($a==$b));then ... fi,无需添加空格了,更加符合 C 的编程语法
, 逗号运算符 1、用在连接一连串的数学表达式中,这串数学表达式均被求值,但只有最后一个求值结果被返回。
2、用于参数替代中,表示首字母小写,如果是两个逗号,则表示全部小写,注意,这个特性在bash version 4的时候被添加的。

expr使用方法

# 
]# cat e1.sh 
#!/bin/bash
#
num1=100
num2=101
x=`expr $num1 + $num2`       # 引用时注意左右空格          
x1=`expr $num1 \* $num2`     # 如果是 乘法 需要先转义一下
x2=`expr $num1 - $num2`
x3=`expr $num1 / $num2`
x4=`expr $num1 % $num2`

]# expr 1 + 3   也需要注意左右空格, 计算时乘法需要先转义

(())使用方法

]# cat e2.sh 
#!/bin/bash
#
num1=100
num2=191
c1=$((num1+num2))
c2=$((num1-num2))
c3=$((num1*num2))
c4=$((num1/num2))
c5=$((num1%num2))

2.1.5.6、let 算术运算

let 命令取代并扩展了expr 命令的整数算术运, 如 num=100 num2=80

符号 作用 示例
+= 加法 let num+=num2 结果为180
运算过程 let num=num+num2
-= 减法 let num-=num2 结果为20
*= 乘法 let num+=num2 结果为8000
/= 除法 let num+=num2 结果为1
%= 除余 let num+=num2 结果为20

2.1.6、替换符

2.1.6.1、命令替换

命令替换的目的是获取命令的输出,且为变量赋值或对命令的输出做进一步的处理。
命令替换实现的方法为采用$(... )形式引用命令或使用反向引号引用命令’ command’

today=$(date)
today=`date`
# 两个结果一样  2020年 01月 07日 星期二 13:41:15 CST

2.1.6.2、变量替换符

var='hello world'

字段 说明
\${#var} 返回变量中字符串的长度, 结果:11
${var} 变量引用
${var:-default} 如果var没有声明或者为空,则返回default字串,否则返回var自身的值
${:} 偏移pos个字符,取余下的字串, ${var:5}结果: world
${::} 偏移pos个字符,取num个字符长度的字串,用法${var:1:5}。 结果: hello
{,} 逗号分割一般用于文件列表的扩展, echo {a,b}.txt,输出a.txt b.txt
{…} 用于顺序扩展, touch {a..d}.txt,结果为 a.txt b.txt c.txt d.txt
${#} 模式匹配截断,用法${variable#pattern} ,查找值中自左而右第一次被word匹配到的串,并将此串及向左的所有内容都删除。不改变原变量
${##} 模式匹配截断,用法${variable##pattern} ,查找字符串中 从左往右 匹配的深度最深的字符串,匹配完之后删除左边的所有,显示匹配右边字符串的所有值。不改变原变量。
${%} 模式匹配截断,用法${variable%pattern},查找值中 从右往左 第一次被word匹配到的串,并将此串及向右的所有内容都删除。不改变原变量
${%%} 模式匹配截断,用法${variable%%pattern},查找字符串中 从右往左 匹配的深度最深的字符串,匹配完之后删除左边的所有,显示匹配右边字符串的所有值。不改变原变量。
${/ /} 模式匹配替换。${var/pattern/pattern}表示将var字符串的第一个匹配的pattern替换为另一个pattern。不改变原变量。
${// /} 模式匹配替换。${var//pattern/pattern}表示将var字符串中的所有能匹配的pattern替换为另一个pattern。不改变原变量。
]# he="hello world"
]# he2="hello world hello world" 

# ${#}  左边最短匹配模式   # 如果不加*  从顶头开始
]# echo ${he#*o}   # 结果为:world
]# echo ${he2#*o}  # 结果为: world hello world

# ${##}  左边最长匹配模式
]# echo ${he##*o}  #  结果: rld
]# echo ${he2##*o} #  结果: rld   匹配最左边最长的字符串

# ${%}   右边最短匹配模式  注意匹配 * 的位置
]# echo ${he%o*}   #  结果: hello w
]# echo ${he2%o*}  #  结果: hello world hello w

# ${%%}  右边最长匹配模式
]# echo ${he%%o*}  #  结果: hell
]# echo ${he2%%o*} #  结果: hell

# ${/ /}  替换左起的第一个符合的字符串
]# echo ${he2/world/xiong}       结果: hello xiong hello world

# ${// /}  替换所有符合的字符串, 按最深度匹配
]# echo ${he2//world/xiong}     结果: hello xiong hello xiong

2.1.7、运算符

2.1.7.1、逻辑运算符

符号 作用
&& 或 -a 如果前值为true,则执行
|| 或 -o 如果前值为false,则执行
!exp

2.1.7.2、文件运算符

符号 作用
-e file 如果给定的文件存在,则条件测试的结果为真。
-(r|w|x) file 如果给定的文件存在,且是可( 读, 可写,可执行的) 则测试结果为真
-s file 如果给定的文件存在,且其大小大于0
-S file 文件存在且是套接字(socket)
-f file 如果给定的文件存在,且是一个普通文件
-d file 如果给定的文件存在,且是一个目录
-L file 如果给定的文件存在,且是一个符号链接文件
-c file 如果给定的文件存在,且是字符特殊文件
-b file 如果给定的文件存在,且是块特殊文件
-p file 如果给定的文件存在,且是命名的管道文件

linux文件类型

- 普通文件
d 目录
b 块设备
c 字符设备
p 命名管道
l 符号链接
s 套接字

测试demo

# 已知有如下文件,进行判断 
]# ll /run/docker.sock 
srw-rw---- 1 root docker 0 12月 30 08:41 /run/docker.sock
[root@domaster 259]# ll
drwxr-xr-x 2 root root 6 1月   7 13:52 dir
-rw-r--r-- 1 root root 0 1月   7 13:52 file
lrwxrwxrwx 1 root root 4 1月   7 13:52 link -> file

]# cat test.sh 
#!/bin/bash
#
# 判断是否是套接字
[ -S '/run/docker.sock' ] && echo '是一个套接字'
# 判断是否为目录,如果不存在则创建
[ -d './dir' ] && echo '是一个目录' || mkdir ./dir
# 判断是否为文件,如果不存在则touch
[ -f './file' ] && echo '是一个文件' || touch ./file
# 判断是否为符号链接
[ -L './link' ] && echo "是一个软链接" 

2.1.7.3、字符串运算符

符号 作用 示例
= 检测两个字符串是否相等,相等返回 true。 [ \$a = \$b ] 返回 false
!= 检测两个字符串是否相等,不相等返回 true。 [ \$a != \$b ] 返回 true
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false
-n 检测字符串长度是否为0,不为0返回 true。 [ -n $a ] 返回 true
str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true
=~ 正则表达式匹配运算符,用于匹配正则表达式的,配合[[]]使用 if [[ ! $file =~ check$ ]],用于判断 $file 是否是以 check 结尾

demo

]# cat test.sh 
#!/bin/bash
#
value1="xiong"
value2="xion222"

# 判断两个值是否相等,
[ $value1 = $value2 ] && echo 'yep' || echo '不相等'

# 获取docker的pid值,然后在获取docker.sock判断docker是否挂掉,如果都为空说明挂了
pid=`cat /run/docker.pid`

# 判断pid是否为空, 如果为空为true
[ -z '$pid' ] && echo '字符串为空' || echo '字符串有值 ' $pid

# 使用-n会更好判断, 如果不为空为true
[ -n '$pid' ] && echo $pid || echo '字符串为空'

# 判断字符串是否为空,如果非空为true
[ $value2 ] && echo '不为空'  || echo '为空'

2.1.7.4、关系运算符

符号 作用 示例
-eq 检测两个数是否相等,相等返回 true。 [ \$a -eq \$b ] 返回 true
-ne 检测两个数是否相等,不相等返回 true。 [ \$a -ne \$b ] 返回 true
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ \$a -gt $b ] 返回 false
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ \$a -lt $b ] 返回 true
-ge 检测左边的数是否大等于右边的,如果是,则返回 true。 [ \$a -ge $b ] 返回 false
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ \$a -le $b ] 返回 true
[] 一对方括号,用于判断条件是否成立 [ \$a == $b ],注意添加 4 个空格
[[]] 两对方括号是对[]的扩展,可使用<、>、&&、||等运算符 [[ \$a>$b ]],只需要添加左右两边两个空格,
需要注意:使用==与!=时,仍需要4个空格
  1. 运算符 [] 与 [[]] 的区别

    ​ 实际上是 Bash 中 test 命令的简写,即所有的 [ expression ] 等于 test expression。而[[ expression ]]是 Bash 中真正的条件判断语句,其语法更符合编程习惯,建议使用。

  2. Shell 中没有 <= 与 >= 运算符,只能使用 -le 与 -ge 替代。
num=100
num2=91

# 两值相等为true           不相等
[ $num -eq $num2 ] && echo '相等' || echo '不相等'

# 两值不相等为true         不相等
[ $num -ne $num2 ] && echo '不相等' || echo '相等'

# 左边大于右边为true       num大于num2
[ $num -gt $num2 ] && echo 'num大于num2' || echo 'num小于num2'

# 左边小于右边为true       num大于num2
[ $num -lt $num2 ] && echo 'num小于num2' || echo 'num大于num2'

# 左边大于等于右边为true    num大于等于num2
[ $num -ge $num2 ] && echo 'num大于等于num2' || echo 'num小于等于num2'

# 左边小于等于右边为true    num大于等于num2
[ $num -le $num2 ] && echo 'num小于等于num2' || echo 'num大于等于num2'

2.1.8、函数

  1. 自定义函数 - 方式一

    cat one.sh 
    #!/bin/bash
    #
    function test() {
      echo "\$1, \$2: " $1 $2
      echo "\$@: " $@
      echo "\$*: " $*
    }
    
    test 10 20
    
    # 打印结果,  特殊变量在函数中也可以使用
    $1, $2:  10 20
    $@:  10 20
    $*:  10 20
  2. 方式二

    ]# cat two.sh 
    #!/bin/bash
    #
    test() {      # 个人更喜欢这种样式
     echo 'test'
    }

2.1.9、数组

数组元素的下标由0 开始编号,获取数组中的元素要利用下标

2.1.9.1、定义数组

  1. 方式一: array_name=(value1 value2 value3)

  2. 方式二:

    ]# array_name[0]=value0
    ]# array_name[1]=value1
    ]# array_name[2]=value2

2.1.9.2、读取数组

符号 作用
${value[index]} 取出数组的索引值, 从0开始
${value[*]} 获取数组中所有的值
${value[@]} 获取数组中所有的值
${#value[@]} 获取当前数组有多少个值
${#value[index]} 获取单个字符串长度,不加index就是0
${value[*]::} ${数组名[@或*]:开始下标:结束下标}
${value[*]//} 数组值替换,不改变原字符串,${数组名[@或*]/模式/新值}
]# echo ${array_name[2]}    # 结果: value2
]# echo ${array_name[*]}    # 结果: value0 value1 value2
]# echo ${array_name[@]}    # 结果: value0 value1 value2

]# echo ${#array_name[*]}   # 结果:3
]# echo ${#array_name[1]}   # 结果:6
]# echo ${#array_name}      # 结果: 6  默认下标为0 

]# echo ${array_name[@]:0:1}  # 结果: value0
]# echo ${array_name[@]:1}    # 结果: value1 value2

]# echo ${array_name[@]/value1/test}   #  结果: value0 test value2

# 数组遍历打印
]# for v in ${array_name[@]};do echo $v;done
  1. 如果该下标元素已经存在,会怎么样?

    答:会修改该下标的值为新的指定值。
    例如:array_name[2]=100,数组被修改为(value0 value1 100)
  2. 如果指定的下标已经超过当前数组的大小,如上述的arr_number的大小为2,指定下标为10或者11或者大于2的任意值会如何?

    答:新赋的值被追加到数组的尾部。
    例如:arr_number[13]=13,数组被修改为(value0 value1 value2 13)

2.1.9.3、删除操作

清除某个元素:unset arr_number[1],这里清除下标为1的数组;
清空整个数组:unset arr_number;

2.2、shell中控制流结构

Shell 中的控制结构

  • if ... then ... else ... fi
  • case 语句 ;; esac
  • for 循环
  • until 循环
  • while 循环
  • break 控制
  • continue 控制

ps: 一般工作脚本用的最多就是 if for case while

# 如 if   每个 ; 都做为换行
if 条件; then 语句; else 语句; fi 

# 如 if  else if 
if 条件; then 语句 else if 条件;then 语句; else; 命令; fi

# case用的最多,systemD风格脚本,  centos 7.4以后已不在使用
#!/bin/bash
#
read -p "请输入选项: " -t 5 CHIOSE
AUTO_CHIOSE=3
CHIOSE=${CHIOSE:-$AUTO_CHIOSE}   # 超时就打印帮助选项, 
case $CHIOSE in
  1|start)
     echo 'start|1' ;;
  2|stop)
     echo "stop|2" ;;
  3|other)
     echo -e "\t\tUsage scrpt ( start | stop | other )\n\n" ;;
esac
# for 的几种用法

#!/bin/bash
#
for i in {1..10};do     # 用花括号直接展开,这个最方便
  echo $i
done

# seq [起如数 [步进长度]] 结束数` 
for u in `seq 1 1 10`;do   # 如果有开发,使用这种就一目了然,序号步进
  echo "u: "$u
done

for ((i=0;i<=10;i++ ));do  # 这种叠加也不错, 个人用的少,第一种多
   echo $i
done