讲义
1. shell是一种脚本语言 和传统的开发语言比较,会比较简单
2. shell有自己的语法;可以使用逻辑判断、循环等语法
3. 可以自定义函数,目的就是为了减少重复的代码
4. shell是系统命令的集合
5. shell脚本可以实现自动化运维,能大大增加我们的运维效率
1. 开头需要加 #!/bin/bash
2. 以 # 开头的行作为解释说明
3. 脚本的名字以 .sh 结尾,用于区分这是一个 shell 脚本
[root@test01 shell]# vi 01.sh
#!/bin/bash #固定开头格式
#written by sc #固定开头格式,意思是谁写的
#2019-06-17 #固定开头格式,意思是年月日
echo "123" #打印 123
w #查看负载
ls #查看当前目录
[root@test01 shell]# sh 01.sh
123
19:46:25 up 2:41, 2 users, load average: 0.05, 0.03, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.85.1 16:47 2:16m 0.07s 0.01s vi 01.sh
root pts/1 192.168.85.1 19:43 1.00s 0.11s 0.00s sh 01.sh
01.sh
方法一:
/bin/sh实际是bash的软连接;其实是真正执行的是bash
[root@test01 shell]# ls -l /bin/bash
-rwxr-xr-x. 1 root root 964608 Oct 31 2018 /bin/bash
[root@test01 shell]# ls -l /bin/sh
lrwxrwxrwx. 1 root root 4 Mar 19 07:53 /bin/sh -> bash
[root@test01 shell]# bash 01.sh
123
09:46:46 up 39 min, 1 user, load average: 0.30, 0.16, 0.10
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.85.1 09:33 6.00s 0.10s 0.00s w
01.sh
方法二:
[root@test01 shell]# chmod a+x 01.sh #增加执行权限
[root@test01 shell]# ./01.sh #可执行脚本
123
22:03:55 up 4:59, 1 user, load average: 0.02, 0.04, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/1 192.168.85.1 19:43 3.00s 0.09s 0.00s /bin/bash ./01.sh
01.sh
[root@test01 shell]# sh -x 01.sh
+ echo 123
123
+ w
09:40:43 up 33 min, 1 user, load average: 0.00, 0.02, 0.06
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.85.1 09:33 3.00s 0.08s 0.01s w
+ ls
01.sh
[root@test01 shell]# vim 01.sh
#!/bin/bash
echo "123 #注意:为了测试 bash -n 把123右侧的双引号去掉
w
ls
[root@test01 shell]# sh -n 01.sh #执行脚本
01.sh: line 2: unexpected EOF while looking for matching `"' #检查完以后显示语法是错的
01.sh: line 5: syntax error: unexpected end of file
时间格式举例:
[root@test01 shell]# date +%Y #大写Y 年份2019
2019
[root@test01 shell]# date +%y #小写y 简写的年 年份19
19
[root@test01 shell]# date +%m #小写m 月份06
06
[root@test01 shell]# date +%M #分钟22
22
[root@test01 shell]# date +%d #日期16
16
[root@test01 shell]# date +%D #年月日20190616
06/16/19
[root@test01 shell]# date +%F #日期格式2019-06-16
2019-06-16
[root@test01 shell]# date +%H #大写H 小时11
11
[root@test01 shell]# date +%h #小写h 英文的月
Jul
[root@test01 shell]# date +%S #大写S 秒54
54
[root@test01 shell]# date +%T=date +%H:%M:%S #常规时间11:42:40
11:42:40
[root@test01 shell]# date +%w #星期几0
0
[root@test01 shell]# date +%W #今天是今年的第23周
23
日历:
[root@test01 shell]# cal #显示当月日历
June 2019
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
[root@test01 TD]# cal 11 2019 #显示指定月年
November 2019
Su Mo Tu We Th Fr Sa
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
时间戳举例:
[root@test01 shell]# date +%s #小写s 时间戳1560656445
1560656445
[root@test01 shell]# date -d @1560656445
Sun Jun 16 11:40:45 CST 2019
[root@test01 shell]# date +%s -d "2019-06-16 11:40:45"
1560656445
-1,+1 年月日举例:
[root@test01 shell]# date -d "-1 day" +%F #一天前
2019-06-15
[root@test01 shell]# date -d "+1 day" +%F #一天后
2019-06-17
[root@test01 shell]# date -d "-1 week" +%F #一周前
2019-11-11
[root@test01 shell]# date -d "+1 week" +%F #一周后
2019-11-25
[root@test01 shell]# date -d "-1 month" +%F #一月前
2019-05-16
[root@test01 shell]# date -d "+1 month" +%F #一月后
2019-07-16
[root@test01 shell]# date -d "-1 year" +%F #一年前
2018-06-16
[root@test01 shell]# date -d "+1 year" +%F #一年后
2020-06-16
-1,+1 小时分钟举例:
[root@test01 shell]# date -d "-1 hour" +%T #一小时前
11:06:03
[root@test01 shell]# date -d "+1 hour" +%T #一小时后
13:06:13
[root@test01 shell]# date -d "-1 min" +%T #一分钟前
12:06:26
[root@test01 shell]# date -d "+1 min" +%T #一分钟后
12:08:33
讲义
1. 当脚本中使用某个字符串较频繁并且字符串长度很长时就应该使用变量代替(比如a=jdjjdjdddx)
2. 使用条件语句时,常使用变量 if [ $a -gt 1 ]; then ... ; fi
3. 引用某个命令的结果时,用变量替代 n=wc -l 1.txt
4. 写和用户交互的脚本时,变量也是必不可少的 read -p "Input a number: " n; echo $n 如果没写这个n,可以直接使用$REPLY
5. 内置变量 $0, $1, $2… $0表示脚本本身,$1 第一个参数,$2 第二个 .... $#表示参数个数
6. 数学运算a=1;b=2; c=$(($a+$b))或者$[$a+$b]
讲义
1. 格式1:if 条件 ; then 语句; fi
2. 格式2:if 条件; then 语句; else 语句; fi
3. 格式3:if …; then … ;elif …; then …; else …; fi
4. 逻辑判断表达式:if [ $a -gt $b ]; if [ $a -lt 5 ]; if [ $b -eq 10 ]等 -gt (>); -lt(<); -ge(>=); -le(<=);-eq(==); -ne(!=) 注意到处都是空格
5. 可以使用 && || 结合多个条件
6. if [ $a -gt 5 ] && [ $a -lt 10 ]; then
7. if [ $b -gt 5 ] || [ $b -lt 3 ]; then
#!/bin/bash #开头固定格式
a=5 #变量 a=5
if [ $a -gt 3 ] #if是判断条件,变量a大于3的时候
then #固定格式
echo ok #输出ok
fi #固定格式
#!/bin/bash #开头固定格式
a=1 #变量 a=1
if [ $a -gt 3 ] #if是判断条件,变量a大于3的时候
then #固定格式
echo ok #输出ok
else #else表示除if以外,剩下的情况
echo nook #输出nook
fi #固定格式
#!/bin/bash #开头固定格式
read -p "Please enter your test sco:" a #输入的数字赋值到了a
if [ $a -lt 60 ] #if是判断条件,赋值小于60
then #固定格式
echo "Too bad the" #打印 Too bad the
elif [ $a -gt 60 ] && [ $a -lt 85 ] #elif除if判断条件以外,另外的判断条件,赋值大于60并且小于85
then #固定格式
echo "Ok!" #打印 ok
else #else表示除上面if和elif判断以外,剩下的情况
echo "Good!" #打印 good
fi #固定格式
[root@test01 shell]# sh if03.sh
Please enter your test sco:45
Too bad the
[root@test01 shell]# sh if03.sh
Please enter your test sco:66
Ok!
[root@test01 shell]# sh if03.sh
Please enter your test sco:99
Good!
符号 | 含义 |
---|---|
-gt | 大于 |
-lt | 小于 |
-eq | 等于 |
-ne | 不等于 |
-ge | 大于等于 |
-le | 小于等于 |
if [ $a -gt 5 ] && [ $a -lt 10 ]; then
if [ $b -gt 5 ] || [ $b -lt 3 ]; then
讲义
[ -f file ]判断是否是普通文件,且存在
[ -d file ] 判断是否是目录,且存在
[ -e file ] 判断文件或目录是否存在
[ -r file ] 判断文件是否可读
[ -w file ] 判断文件是否可写
[ -x file ] 判断文件是否可执行
#!/bin/bash #开头固定格式
f="/tmp/sclinux" #变量
if [ -f $f ] #判断/tmp/sclinux是否是普通文件,且存在
then #固定格式
echo $f exist #打印/tmp/sclinux存在
else #else表示除if以外,剩下的情况
touch $f #创建/tmp/sclinux
fi #固定格式
[root@test01 shell]# sh -x file01.sh #执行脚本
+ f=/tmp/sclinux
+ '[' -f /tmp/sclinux ']'
+ touch /tmp/sclinux #如果/tmp/sclinux这个文件不存在,创建
[root@test01 shell]# sh -x file01.sh #再次执行脚本
+ f=/tmp/sclinux
+ '[' -f /tmp/sclinux ']'
+ echo /tmp/sclinux exist
/tmp/sclinux exist #/tmp/sclinux已经显示存在
#!/bin/bash #开头固定格式
f="/tmp/sclinux" #变量
if [ -d $f ] #判断/tmp/sclinux是否是目录,且存在
then #固定格式
echo $f exist #打印/tmp/sclinux存在
else #else表示除if以外,剩下的情况
touch $f #创建/tmp/sclinux
fi #固定格式
[root@test01 shell]# sh -x file02.sh #执行脚本
+ f=/tmp/sclinux
+ '[' -d /tmp/sclinux ']'
+ touch /tmp/sclinux
#虽然文件和目录都存在,但是可以重复touch的,摸一下的意思,改变的是atime,mtime,ctime
#!/bin/bash #开头固定格式
f="/tmp/sclinux" #变量
if [ -e $f ] #判断/tmp/sclinux判断文件或目录是否存在
then #固定格式
echo $f exist #打印/tmp/sclinux存在
else #else表示除if以外,剩下的情况
touch $f #创建/tmp/sclinux
fi #固定格式
root@test01 shell]# sh -x file03.sh
+ f=/tmp/sclinux
+ '[' -e /tmp/sclinux ']'
+ echo /tmp/sclinux exist
/tmp/sclinux exist
#!/bin/bash
f="/tmp/sclinux"
if [ -r $f ]
then
echo $f readable
fi
[root@test01 shell]# sh file03.sh
/tmp/sclinux readable
#!/bin/bash
f="/tmp/sclinux"
if [ -w $f ]
then
echo $f writeable
fi
[root@test01 shell]# sh file03.sh
/tmp/sclinux writeable
#!/bin/bash
f="/tmp/sclinux"
if [ -x $f ]
then
echo $f exeable
fi
[root@test01 shell]# sh file03.sh #因为不可执行,所以没有任何的输出
f="/root/ceshi"
[ -f $f ] && rm -f $f #前一条命令执行成功才会继续执行之后的命令
等同于下面的表达方式
if [ -f $f ]
then
rm -rf $f
fi
f="/root/ceshi"
[ -f $f ] || touch $f #前面命令不成功时,执行后面的命令
等同于下面的表达方式
if [ ! -f $f ] # “!” 取反的意思,表示了如果这条命令不成功,就往下执行
then
touch $f
fi
讲义
if特殊用法
1. if [ -z "$a" ] 逻辑条件是:变量a的值为空
2. if [ -n "$a" ] 逻辑条件是:变量a的值不为空
3. if grep -wq '123' 1.txt; then 逻辑条件是:1.txt中含有'123'的行
4. if [ ! -e file ]; then 逻辑条件是:文件不存在
圆括号与方括号的区别:
1. if (($a<1)); then … 等同于 if [ $a -lt 1 ]; then…
2. [ ] 中不能使用<,>,==,!=,>=,<=这样的符号
1. if -z或者if -n 都不能作用在文件上,只能作用在变量上。
2. if [ -z "$a" ] 这个表示当变量a的值为空时会怎么样
3. !-z=-n
4. !-n=-z
#!/bin/bash
n=`wc -l /etc/passwd |awk '{print $1}'` #变量/etc/passwd的行数截取第一段
if [ -z "$n" ] #条件:是否为空
then #固定格式
echo error #如果为空打印错误
exit #如果为空退出
elif [ $n -gt 20 ] #如果变量n的赋值于20
then #固定格式
echo ok #打印ok
fi #固定格式
[root@test01 shell]# sh -x if04.sh
++ awk '{print $1}'
++ wc -l /etc/passwd
+ n=35
+ '[' -z 35 ']'
+ '[' 35 -gt 20 ']'
+ echo ok
ok
-n 判断变量的时候,需要用""双引号引起来,若是文件的时候,则不需要用双引号引起来
[root@test01 shell]# if [ -n file3.sh ]; then echo ok; fi
ok
[root@test01 shell]# if [ -n "$b" ]; then echo $b; else echo "b is null"; fi
b is null
讲义
case格式:
case 变量名 in
value1)
command
;;
value2)
command
;;
*)
commond
;;
esac
如果case中的某个value是一样的,我们可以这样写:
在case程序中,可以在条件中使用 |,表示或的意思,
比如
2|3)
command
;;
#输入非数字,或者大于100,并且输入任意数字可以显示出来
#!/bin/bash
read -p "Please input a number: " n #请输入数字
if [ -z "$n" ] #如果为空
then
echo "Please input a number." #请输入数
exit 1 #退出并返回一个值
fi
n1=`echo $n|sed 's/[0-9]//g'` #打印出的数字,过滤其中只要包含0-9就为空
if [ -n "$n1" ] #如果这个变量不为空
then
echo "Please input a number." #请继续输入数字
exit 1 #退出并返回一个值
fi
if [ $n -ge 0 ] && [ $n -lt 60 ] #>=0并且<60
then
tag=1 #标签1
elif [ $n -ge 60 ] && [ $n -lt 85 ] #>=60并且<85
then
tag=2 #标签2
elif [ $n -ge 85 ] && [ $n -lt 100 ] #>=85并且<100
then
tag=3 #标签3
else [ $n -ge 100 ] #>=100
tag=4 #标签4
fi
case $tag in
1)
echo "not ok" #标签1显示 "not ok"
;;
2)
echo "ok" #标签2显示 "ok"
;;
3)
echo "That's great" #标签3显示 That's great"
;;
4)
echo "Very good" #标签4显示 "Very good"
;;
esac
重复执行一系列命令在 编程中很常见。通常你需要重复一组命令直到达到某个特定条件,比如处理某个目录下的所有文件、系统上的所有用户或者是某个文本文件中的所有行。
常见的两种循环,在脚本中普遍被用到。
for循环
while循环
#!/bin/bash
sum=0
for i in `seq 1 100` #打印1-100的数字,i是变量
do
sum=$[$sum+$i] #求和的固定格式
done
echo $sum #打印sum值
#查看/root/shell/下的所有文件
#!/bin/bash
cd /root/shell/
for i in ls /root/shell/
do
if [ -d $i ]
then
ls $i
fi
done
[root@sc01 shell]# sh -x 3.sh
+ cd /root/shell/
+ for i in ls /root/shell/
+ '[' -d ls ']'
+ for i in ls /root/shell/
+ '[' -d /root/shell/ ']'
+ ls /root/shell/
1.sh 2.sh 3.sh test.sh
每隔30秒检查一下系统负载,当系统的负载大于10的时候,发一封邮件(监控脚本) 最小单元是任务计划 cron
#!/bin/bash
while :
#冒号:表示死循环的意思,或者1,或者 true都是死循环
do
load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d. -f1`
#代码名词释义
#w #查看系统负载
#uptime #可以直接显示 w 系统负载的第一行,就可以省去 head -1
#head -1 #取第一行
#awk -F 'load average: ' '{print $2}' #以'load average: '分隔,输出第二段
#cut -d . -f1 #以 . 分隔 取第一段
if [ $load -gt 10 ]
then
/usr/local/sbin/mail.py test_emali_0711@163.com"load high" "$load"
fi
sleep 30 #休眠30秒,因为检查系统负载,不需要一直去检查,过一会再看
done
#!/bin/bash
while :
do
read -p "Please input a number: " n #请输入数字
if [ -z "$n" ] #如果输入的为空
then
echo "请输入数字" #请输入数字
continue #重复循环
fi
n1=`echo $n|sed 's/[0-9]//g'` #变量,打印的数字,过滤其中0-9数字为空
if [ -n "$n1" ] #如果不为空
then
echo "请输入纯数字" #请输入纯数字
continue #重复循环
fi
break #跳出循环
done
echo $n #打印 $n 的结果
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
break
fi
echo $i
done
echo aaaaaa
[root@test01 shell]# sh -x break.sh
++ seq 1 5
+ for i in '`seq 1 5`'
+ echo 1
1
+ '[' 1 -eq 3 ']'
+ echo 1
1
+ for i in '`seq 1 5`'
+ echo 2
2
+ '[' 2 -eq 3 ']'
+ echo 2
2
+ for i in '`seq 1 5`'
+ echo 3
3
+ '[' 3 -eq 3 ']'
+ break
+ echo aaaaaa
aaaaaa
[root@test01 shell]# sh break.sh
1
1
2
2
3
aaaaaa
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
continue
fi
echo $i
done
echo aaaaaa
[root@test01 shell]# sh continue.sh
1
1
2
2
3
4
4
5
5
aaaaaa
#!/bin/bash
for i in `seq 1 5`
do
echo $i
if [ $i -eq 3 ]
then
exit
fi
echo $i
done
echo $i
[root@test01 shell]# sh exit
1
1
2
2
3
select也是循环的一种,它比较适合用在用户选择的情况下
比如,我们有一个这样的需求,运行脚本后,让用户去选择数字,选择1,会运行w命令,选择2运行top命令,选择3运行free命令,选择4退出。脚本这样实现
#!/bin/bash
echo "Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit"
echo
select command in w top free quit
do
case $command in
w)
w
;;
top)
top
;;
free)
free
;;
quit)
exit
;;
*)
echo "Please input a number:(1-4)."
;;
esac
done
[root@test01 shell]# sh select.sh
Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit
1) w
2) top
3) free
4) quit
#? 1
13:17:03 up 19:00, 1 user, load average: 0.07, 0.06, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.85.1 08:33 7.00s 0.22s 0.21s -bash
#? 3
total used free shared buff/cache available
Mem: 1005628 691060 66148 8200 248420 110332
Swap: 2097148 264 2096884
#? 4
[root@test01 shell]#
我们发现,select会默认把序号对应的命令列出来,每次输入一个数字,则会执行相应的命令,命令执行完后并不会退出脚本。它还会继续让我们再次输如序号。序号前面的提示符,我们也是可以修改的,利用变量PS3即可,再次修改脚本如下
#!/bin/bash
PS3="Please select a number: "
echo "Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit"
echo
select command in w top free quit
do
case $command in
w)
w
;;
top)
top
;;
free)
free
;;
quit)
exit
;;
*)
echo "Please input a number:(1-4)."
;;
esac
done
[root@test01 shell]# sh select.sh
Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit
1) w
2) top
3) free
4) quit
Please select a number: 1
13:19:38 up 19:03, 1 user, load average: 0.14, 0.09, 0.06
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.85.1 08:33 2.00s 0.21s 0.21s -bash
Please select a number: 3
total used free shared buff/cache available
Mem: 1005628 691056 66000 8200 248572 110324
Swap: 2097148 264 2096884
Please select a number: 4
[root@test01 shell]#
如果想要脚本每次输入一个序号后就自动退出,则需要再次更改脚本如下
#!/bin/bash
PS3="Please select a number: "
echo "Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit"
echo
select command in w top free quit
do
case $command in
w)
w;exit
;;
top)
top;exit
;;
free)
free;exit
;;
quit)
exit
;;
*)
echo "Please input a number:(1-4)."
;;
esac
done
[root@test01 shell]# sh select.sh
Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit
1) w
2) top
3) free
4) quit
Please select a number: 1
13:24:09 up 19:07, 1 user, load average: 0.00, 0.04, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.85.1 08:33 1.00s 0.22s 0.22s -bash
[root@test01 shell]#
shell函数定义:shell函数相当于一个子shell,就是把一段代码整理到了一个小单元中,并给这个小单元起一个名字,当用到这段代码时直接调用这个小单元的名字即可。
function f_name() {
command
}
用于定义加法的函数,shell中定义的函数,必须放在最前面
在shell里面需要优先定义函数,比如在调用这个函数的时候,函数还没有定义,就会报错
在想要调用哪一个函数,就必须在调用语句之前,先定义这个函数
注释:
function 后是函数的名字,并且 function 这个单词是可以省略掉的
花括号{} 里面为具体的命令
函数,可以直接写在脚本内,相当于直接调用
內建变量含义:
$1 第一个参数
$2 第二个参数
$3 第三个参数
...
~
$n 第n个参数
$# 总共有几个参数
$0 脚本名字
#!/bin/bash #开头固定格式
function input() #函数 自定义名称:input
{ #固定格式
echo '$1'=$1 '$2'=$2 'S3'=$3 '$0'=$0 '$#'=$# #内建变量参数
} #固定格式
input a b c #定义参数内容
[root@test01 shell]# sh function.sh
$1=a $2=b S3=c $0=function.sh $#=3
[root@test01 shell]# sh -x function.sh
+ input a b c
+ echo '$1=a' '$2=b' S3=c '$0=function.sh' '$#=3'
$1=a $2=b S3=c $0=function.sh $#=3
#!/bin/bash #开头固定格式
function sum() #函数 自定义名称:sum
{ #固定格式
s=$[$1+$2] #内建变量参数
echo SUM=$s #打印变量值
} #固定格式
sum 10 20 #定义参数内容
[root@test01 shell]# sh function01.sh
SUM=30
[root@test01 shell]# ifconfig |grep -A1 "ens33: " #在网卡里过滤 ens33: 当前行和下一行
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.85.130 netmask 255.255.255.0 broadcast 192.168.85.255
[root@test01 shell]# ifconfig |grep -A1 "ens33: " |awk '/inet/ {print $2}' #过滤出含有 inet 行,第二段内容,分段符默认为空格
192.168.85.130
#!/bin/bash #开头固定格式
ip() #函数 自定义名称:ip
{ #固定格式
ifconfig |grep -A1 "$1: " |awk '/inet/ {print $2}' #网卡里过滤当前行和下一行参数,并且过滤 inet 行第二段内容
} #固定格式
read -p "Please input the eth name: " eth #输入的内容赋值到了eth
ip $eth #ip定义变量
[root@test01 shell]# sh function02.sh
Please input the eth name: ens37
192.168.85.130
[root@test01 shell]# sh function02.sh
Please input the eth name: ens33:0
192.168.94.150
[root@test01 shell]# sh function02.sh
Please input the eth name: ens37
192.168.159.130
[root@test01 shell]# b=(1 2 3 4) #定义数组b,1 2 3 4为其元素
[root@test01 shell]# echo ${b[@]} #方法一:查看数组元素
1 2 3 4
[root@test01 shell]# echo ${b[*]} #方法二:查看数组元素
1 2 3 4
[root@test01 shell]# echo ${b[1]} #查看数组元素b1,即第二位
2
[root@test01 shell]# echo ${b[4]} #查看数组元素b4,为空,因为只有4位,b4即为第五位
[root@test01 shell]# echo ${b[0]} #b[0]=1 为第一位
1
[root@test01 shell]# echo ${#b[@]} #查看数组元素总数 加#号
4
[root@test01 shell]# echo ${#b[*]}
4
[root@test01 shell]# echo ${b[*]}
1 2 3 4
[root@test01 shell]# b[3]=qq #把qq赋给b3,即第4位
[root@test01 shell]# echo ${b[*]}
1 2 3 qq
[root@test01 shell]# b[3]=100 #把100赋给b3,即第4位
[root@test01 shell]# echo ${b[*]}
1 2 3 100
[root@test01 shell]# b[5]=100 #把100赋给b5,因为b5不存在,则自动创建;注意b4不存在
[root@test01 shell]# echo ${b[*]}
1 2 3 100 100
[root@test01 shell]# b[4]=dd #把dd赋给b4,即第5位;注意b5的区别
[root@test01 shell]# echo ${b[*]}
1 2 3 100 dd 100 #第5位为dd,证明b4之前为空
[root@test01 shell]# echo ${b[*]}
1 2 3 100 dd 100
[root@test01 shell]# unset b[5] #删除b5元素,即第6位
[root@test01 shell]# echo ${b[*]} #成功删除100
1 2 3 100 dd
[root@test01 shell]# unset b #清空数组元素
[root@test01 shell]# echo ${b[*]}
[root@test01 shell]# a=(`seq 1 10`) #定义数组a
[root@test01 shell]# echo ${a[*]}
1 2 3 4 5 6 7 8 9 10
[root@test01 shell]# echo ${a[*]:5:4} #从第5位开,截取4位
6 7 8 9
[root@test01 shell]# echo ${a[*]}
1 2 3 4 5 6 7 8 9 10
[root@test01 shell]# echo ${a[*]:0-4:3} #从倒数第5位(0 1 2 3 4)开始,截取3位
7 8 9
[root@test01 shell]# echo ${a[*]}
1 2 3 4 5 6 7 8 9 10
[root@test01 shell]# echo ${a[*]/2/11} #把2替换为11
1 11 3 4 5 6 7 8 9 10
[root@ying01 shell]# echo ${a[*]}
1 2 3 4 12 6 7 8 9 10
[root@ying01 shell]# c=(${a[*]/6/18}) #把更新的数组 赋予c数组
[root@ying01 shell]# echo ${c[*]} #打印c数组
1 2 3 4 12 18 7 8 9 10
select用法 http://www.apelearn.com/bbs/thread-7950-1-1.html
shell多线程 http://blog.lishiming.net/?p=448
给你提供一本电子书 链接:http://pan.baidu.com/s/1mg49Taw 密码:yk4b
shell习题做一下 http://www.apelearn.com/study_v2/chapter15.html#shll