shell脚本进阶

笔记

shell 进阶

顺序执行
选择执行
循环执行

条件判断 if 是关键字

if 如果命令为真 ;执行这个命令,如果为假继续判断;then
elif 如果命令为真 ;执行这个命令,如果为假继续判断
else 如果为假执行这个命令
fi 结束

判断 <18 >=18 and <60 >=60 <=150
vim test_if.sh
#!/bin/bash
read -p “sz: ” AGE
[[ “$AGE” =~ ^[0-9]+$ ]] || { echo age is not digit; exit ; }
if [ “$AGE” -lt 18 ] ;then
echo “good”
elif [ “$AGE” -ge 18 -a “$AGE” -lt 60 ] ;then
echo “good good”
elif [ “$AGE” -ge 60 -a “$AGE” -lt 150 ] ;then
echo “good good good”
else
echo “no no”
fi

如果是1,2,3 执行cm1命令
如果是4,5,6 执行cm2命令
如果是7,8,9 执行cm3命令
这种语句用case

case 变量引用 in
PAT1)
如果是 执行这个命令
PAT2)
如果是 执行这个命令,
*)
如果都不是执行这个命令
esac

例:判断yes还是no

#!/bin/bash
read -p “do you agree?yes or no: ” ANS
if [ -z “$ANS” ] ;then 判断是不是为空
echo “please input yes or no” 提示
exit 退出
fi

case $ANS in 引用变量
[Yy]|[Yy][Ee][Ss]) 如果是yes
echo you answer is YES 执行这个命令
;;
[Nn]|[Nn][Oo]) 如果是no
echo your answer is no 执行这个命令
;;
*) 如果都不是
echo your answer is false 执行这个命令
esac 结束

练习题
1、编写脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参
数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户
的id号等信息

#!/bin/bash
read -p “Please enter the user name: ” NAME
party=`cat /etc/passwd |grep -o “^$NAME”`
if [ “$party” == “$NAME” ] ;then
echo The user already exists
else
useradd $NAME;id $NAME
fi

2、编写脚本/root/bin/yesorno.sh,提示用户输入yes或no,并判断用户输入的
是yes还是no,或是其它信息
#!/bash
#判断yes还是no
read -p “Please enter yes or no: ” AGE
if [ -z “$AGE” ] ;then
echo “Please enter yes or no”
exit
fi

case $AGE in
[Yy]|[Yy][Ee][Ss])
echo you answer is YES
;;
[Nn]|[Nn][Oo])
echo you answer is NO
;;
*)
echo your answer is false
esac

3、编写脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型
(普通,目录,链接,其它文件类型)

read -p “Please enter the file path: ” AGE
if [ -f “$AGE” ] ;then
echo “It’s a normal file.”
elif [ -d “$AGE” ] ;then
echo “This is a directory file ”
elif [ -h “$AGE” ] ;then
echo “This is a link file.”
else
echo “Other file types ”
fi

4、编写脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数

#!/bin/bash
read -p “Please enter the parameters: ” AGE
if [[ “$AGE” =~ ^[0-9]+$ ]] ;then
echo “You entered a positive integer.”
else
echo “Please enter a positive integer”
fi

for 循环适合后面用列表的方式

for语法

for 变量名 in 列表;do
for i in 1 2 3;do
for i in {1..3};do
for i in {1..3};do echo $in ;done

$RANDOM 产生随机数字

bash rectangle.sh 10 20
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-07
#FileName: rectangle.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
#打印矩形
high=$1 #高
width=$2 #宽
for i in `seq $high` ;do
for j in `seq $width` ;do
color=$[RANDOM%7+31] #设置变量color=随机数字31到37
echo -e “\e[1;5;${color}m*\e[0m\c”
#打印*号,1;高亮 5;闪烁。默认换行,还没有打印完成不能换行\c是>不换行
done
echo #执行完一次循环主动换行
done

九九乘法表
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-07
#FileName: 9×9.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..9};do
for j in `seq 1 $i` ;do
result=$[$i*$j] #变量i和变量j相乘在定义一个result的变量
echo -e “${j}x${i}=$result \c” \c是不变行
done
echo #当循环一遍以后自动换行
done

#第一个i变量循环完成以后在从头循环
#例如第一次 1 ; 第2次 1 2 ; 第3次 1 2 3 ;…..

#第2个变量j只循环一次
#例:第一次1 ;第二次 2 ;第三次 3 ; ……

#1和1
#1和2 2和2
#1和3 2和3 3和3
#…….

openssl rand -base64 22 |tr -dc ‘[[:alpha:]]’ |head -c8
随机生成22位字符,只留字母和前8位

openssl rand -base64 22
随机生成22位字符

8、在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字
母,如:1AbCdeFgH.html

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-07
#FileName: html.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in `seq 0 9`;do
for j in `openssl rand -base64 22 |tr -dc ‘[[:alpha:]]’ |head -c8`;do
echo `touch /testdir/$i$j.html` &> /dev/null
done
done

国际象棋
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: script.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..8};do
for j in {1..4};do
if [ $[$i%2] -eq 0 ];then 判断是奇数行还是偶数行
echo -e “\033[1;41m \033[0m\033[1;43m \033[0m\c”
else
echo -e “\033[1;43m \033[0m\033[1;41m \033[0m\c”
fi
done
echo
done

不完美的笨办法
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: script.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..6};do
for j in {4..4};do
#chmo=$[$RANDOM%7+31]
if [ $[$i%2] -eq 0 ];then
echo -e “\033[1;41m \033[0m\033[1;43m \033[0m\c”
echo
echo -e “\033[1;41m \033[0m\033[1;43m \033[0m\c”
echo
echo -e “\033[1;41m \033[0m\033[1;43m \033[0m\c”
else
echo -e “\033[1;42m \033[0m\033[1;41m \033[0m\c”
echo
echo -e “\033[1;42m \033[0m\033[1;41m \033[0m\c”
echo
echo -e “\033[1;42m \033[0m\033[1;41m \033[0m\c”
fi
done
echo
done

如何实现1到100相加等于多少?
方法一:echo {1..100} |tr ” ” “+” |bc

方法二:seq -s + 100 |bc

方法三:vim test_for.sh

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: test_for.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
declare -i sum=0 #declare声明 -i 声明整数 sum=吃饭临时加出来的一个变量,设置一个初始值0
for i in {1..100};do
let sum=sum+i #sum=0+1 sum就等于1; sum=1+2 sum就等于3 ;sum=3+3
done
echo sum=$sum

用for循环新的语法计算1到100的和
sum=0 #设置sum的初始值为0
for ((i=1;i<=100;i++ ));do #i的初始值为1 ;i的范围是<=100 ;i++先执行后加一
let sum=$sum+i # let 是算法 sum=sum初始值加i
done
echo sum=$sum


for ((sum=0,i=1;i<=100;i++ ));do
let sum=$sum+i
done
echo sum=$sum

以3为步进到100 相加
例 1 4 7 10 13 16 19 22 25…….
vim test_for.2.sh
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: test_for.2.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
declare -i sum=0
for i in {1..100..3};do
let sum=sum+i
done
echo sum=$sum

创建十个用户,创建初始化口令
vim 98_createuser.sh

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: 98_createuser.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in user{1..10};do
useradd $i &> /dev/null
if [ $? -eq 0 ] ;then
echo “$i User creation success ”
echo magedu |passwd –stdin $i &> /dev/null
else
echo “$i user already exists”
fi
done

ping 一个特定的网段
vim scanip.sh
net=172.20.102
for i in {1..254};do
{ if ping -c1 -w1 $net.$i &> /dev/null;then
echo $net.$i is up
else
echo $net.$i down
fi; }& # 大括号是并行执行 &是后台执行
done
wait # 执行完成以后自动退出

ping通的加1,显示总共有多少ip可ping通

/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,
以K开头的输出为文件加stop,以S开头的输出为文件名加start,如K34filename stop
S66filename start

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: rc.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in `ls /etc/rc.d/rc3.d/`;do
Ke=`echo $i |grep -o “^K”`
Se=`echo $i |grep -o “^S”`
if [ “$Ke” == K ];then
echo “$i stop”
elif [ “$Se” == S ];then
echo “$i start”
fi
done

while 循环
在循环次数不确定的情况下

while 条件 ;do
如果命令为真执行循环体
如果为假退出循环体
done

用while循环实现 1+2+…100
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: he.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
declare -i sum=o
i=1
while [ $i -le 100 ] ;do
let sum=$sum+$i
let i++
done
echo sum=$sum

九九乘法表用while实现
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: 9×9.2.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
declare -i i=1
while [ $i -le 9 ] ;do
declare -i j=1
while [ $j -le $i ] ;do
result=$[$j*$i]
echo -e “${j}x${i}=$result\t\c”
let j++
done
echo
let i++
done

true 和;的返回值为真

ss -ntl 查看端口

break 退出循环
continue 退出循环

备份挂载点文件

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: fstab.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
#备份fstab文件挂载的点文件
vim fstab.sh
SLEEPTIME=10
while : ;do # ;是永远为真
if ls /etc/fstab &> /dev/null ;then #检查fstab文件在不在
: #如果在什么都不做
else # 如果不存在 则执行下面的操作
touch /etc/fstab
echo UUID=89dd391f-1b8b-425c-aefd-cde126d69937 / xfs defaults 0 0 >> /etc/fstab
echo UUID=996c6eae-1ecf-440c-a9da-077d5f7f42da /app xfs defaults 0 0 >> /etc/fstab
echo UUID=d49627c3-2bab-42ea-875b-4dae74140522 /boot xfs defaults 0 0 >> /etc/fstab
echo UUID=59d933de-9b7c-4f8b-80d1-7bff7b65e490 swap swap defaults 0 0 >> /etc/fstab
echo /dev/sr0 /mnt/cdrom iso9660 defaults 0 0 >> /etc/fstab
echo at `date “+%F %T”` Recreate the fstab file >> /data/fstab.log #将更改的时间放到日志文件
fi
sleep $SLEEPTIME #休眠10秒
done

1、 编写脚本,求100以内所有正奇数之和
vim figure.sh

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: figure.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
declare -i sun=0
while : ;do
for i in {1..100..2} ;do
let sun=$sun+$i
done
break
done
echo sun=$sun

until 条件 ;do
条件为假执行循环
条件为真则退出循环
done

continue 结束本次循环

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: continue.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..10};do
if [ $i -eq 5 ] ;then continue;fi # 如果$i等于5就不执行,继续执行6
echo i=$i
done

continue 结束外层的循环
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: continue.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..10};do
for j in {1..10};do
if [ $j -eq 5 ] ;then continue 2;fi # 如果$i等于5就不执行 就结束最外层的循环,继续下一个循环
echo j=$j
done
done

break 结束全部循环

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: continue.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..10};do
if [ $i -eq 5 ] ;then break;fi # 如果$i等于5就不执行循环
echo i=$i
done

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: continue.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..3};do
for j in {1..10};do
if [ $j -eq 5 ] ;then break;fi # 如果$j等于5就不执行本次循环,继续执行下次循环
echo j=$j
done
echo
done
~

break 2
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-08
#FileName: continue.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
for i in {1..3};do
for j in {1..10};do
if [ $j -eq 5 ] ;then break 2;fi # 如果$j等于5就结束外层的全部循环
echo j=$j
done
echo
done

shift 把参数列表往左移
默认可以往左移1位,可以移多位

创建多个用户
until [ -z “$1” ] ;do #判断$1是否为空,如果不为空就退出循环
useradd $1 #创建用户
echo “$1 is create”
shift #当执行完一个任务,然后往左移
done
echo “done”

随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出

#!/bin/bash
sun=$[$RANDOM%11] #自动生成一个随机数
while read -p “Please enter a number from 1 to 10: ” AGE ;do #请用户输入1到10的数字
[[ “$AGE” =~ [0-9] ]] || { echo “Please enter a number from 1 to 10 ” ; continue ; } #判断用户输入的是1到10之间的数字,如果不是提示并退出
if [ “$sun” -gt “$AGE” ];then #判断是否大于随机数
echo “little”
elif [ “$sun” -lt “$AGE” ];then #判断是否小于随机数
echo “more”
else
break #如果是退出
fi
done

unset 删除变量和函数

while read line 特殊的while ,能读取文件和命令

查看UID是偶数的行

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-09
#FileName: n1.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
while read line ;do
uid=`echo $line |cut -d: -f3`
user=`echo $line |cut -d: -f1`
[ $[$uid%2] -eq 0 ] && echo “$user:$uid”
done < /etc/passwd

读入/etc/passwd 文件的一行然后付给line,然后执行循环,如果完成以后继续读入继续执行

内存大于10%报警
df | while read disk ;do
if echo $disk | grep “^/dev/sd” > /dev/null ;then
used=`echo $disk |sed -r ‘s/.* ([0-9]+).*/\1/’`
device=`echo $disk |cut -d ” ” -f1`
[ $used -ge 10 ] && echo “$device will be full,used:$used%”
fi
done

做一个列表
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-10
#FileName: s1.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
#%-5s,-是左对齐,左对齐宽度为5的字符串 ,如果不加-默认右对齐
#%-4.2f:.2是保留两位小数点
# \n 是换行符
printf “%-5s %-10s %-4s\n” NO Name Mark
printf “%-5s %-10s %-4.2f\n” 1 Sarath 80.3456
printf “%-5s %-10s %-4.2f\n” 2 James 90.787687
printf “%-5s %-10s %-4.2f\n” 3 Sarath 70.09987

select 循环和菜单
默认死循环

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-10
#FileName: select_menu.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
select mamu in yuto chaomian bingjiling;do #mamu是变量
case $mamu in
yuto) #如果是yuto
echo $mamu price is 888 #执行这个命令
break #并退出循环
;;
chaomian)
echo $mamu price is 66
break
;;
bingjiling)
echo $mamu price is 666
break
esac
done

更改select 菜单里面的提示符
PS3=”please choose the menu(1-3):”
select mamu in yuto chaomian bingjiling;do #mamu是变量
case $mamu in
yuto) #如果是yuto
echo $REPLY:$mamu price is 888 #执行这个命令
break #并退出循环
;;
chaomian)
echo $REPLY:$mamu price is 66
break
;;
bingjiling)
echo $REPLY:$mamu price is 666
break
esac
done

信号捕捉trap
例:
trap ‘echo press ctrl+c’ 2 #捕捉2信号,如果捕捉到就打印echo press ctrl+c,继续执行
for ((i=0;i<=10;i++));do
echo $i
sleep 0.5
done

例:
trap ” 2 #捕捉2信号,如果捕捉到什么都不显示忽略ctrl+c
for ((i=0;i<=10;i++));do
echo $i
sleep 0.5
done

例:
trap ‘-‘ 2 #捕捉2信号,如果捕捉到还原2信号的操作
for ((i=0;i<=10;i++));do
echo $i
sleep 0.5
done

trap -p 打印信号

判断当前用户是root还是普通用户
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-10
#FileName: uid.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
if [ $UID -eq 0 ] ;then
echo then is root
else
echo then is wang
fi

函数的调用

函数的语法

函数名 () {
想执行的命令
}

可以在交互环境中执行也就是当前登陆的界面定义函数,也可以在脚本中定义函数
分号;的意思是里面可能有多个命令,一起执行
1.在交互环境中定义函数
funcl () { echo func1; }
只是定义了一个函数,没有执行
要执行可以向命令一样执行 ,直接写函数名,它会打印echo func1

declare -f 查看系统中所有定义的函数
declare -f funcl 查看自己刚定义的函数

unset funcl
删除函数和删除变量一样

如果在函数里面定义一个变量,在当前的shell还可以调用变量,函数的生效环境是当前shell不是子shell,没有开启子shell
func1 () { name=mage;echo “func1:$name”; }

函数中定义的变量希望在当前的函数中有效,不希望在外面的shell有效
可以在定义变量前加一个特殊字符 local
func1 () { local name=mage;echo “func1:$name”; }

func1 () { declare -i num=100;echo funcl=$num; }
一旦用declare -i声明和定义local一样

在脚本中定义函数,并调用函数
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-10
#FileName: colour.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
sum=`echo $[$RANDOM%9+31]` #随机生成一个数字
colour () { #声明函数
echo -e “\e[1;${sum}m`date`\e[0m” #使命令date加上随机颜色
}
colour #调用函数

func1 () { echo arg:$1 ; echo arg:$2 ; echo all args:$@ ; echo number:$# ; }
第一个字符是arg:$1 用$1表示
第二个字符是arg:$2 用$2 表示
第三个是所有字符args:$@ 用$@ 表示
第四个是所有字符的个数 number:$# 用$# 表示

判断打印的颜色是正着打印还是反着打印
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-10
#FileName: colour.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
colour () { #定义函数
if [ “$1” = “-r” ] ;then #判断是不是有函数后面有没有跟-r
echo -e “\e[1;43m \e[1;41m \e[0m”;return #如果跟了-r就执行这个命令,并用return退出函数本身,
不退出脚本
fi
echo -e “\e[1;41m \e[1;43m \e[0m”
}
colour -r #调用函数加-r
colour #调用函数

判断系统的版本是6还是7
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-10
#FileName: version.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
version () {
bb=`cat /etc/centos-release |sed -r ‘s/.* ([0-9]+).[0-9].*/\1/’`
if [ “$bb” -eq 7 ];then
echo “7”
elif [ “$bb” -eq 6 ];then
echo “6”
fi
}
version

计算两个数字之和
digit () { echo $[$1+$2]; }
digit 1 3

在脚本里面调用函数
将函数写入文件vim functions
然后在脚本调用
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-10
#FileName: call.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
source functions #用source 调用functions文件
colours #调用函数
colours -r
version
colour
export -f colour
./f2.sh

如果还有别的脚本要调用函数要声明成全局变量
例:
export -f colour

在系统中有自定义的函数
/etc/init.d/function 文件里面放的都是各种函数

其中有一个 action函数可以定义命令的命令的成功还是失败
例:可以使命令成功
[root@centos6 init.d]#action “command successful”
command successful [ OK ]

可以使命令失败
[root@centos6 init.d]#action “command successful” /bin/false
command successful [FAILED]

函数递归调用

变量:存储单个元素的内存空间
数组:多个相同类型的元素集合
在元素上加索引也叫下标
数值索引:一般从0开始的索引 0 1 2 3 4 5 6
关联索引:索引可以自定义
稀疏索引:索引不连贯 例: 0 1 2 4 5 7
bash4.0以后的版本才支持数组索引

添加数组的时候要声明数组
数组分为:普通数组,和关联数组
普通数组 -a 不用声明数组,当建议声明
关联数组 -A 必须声明
普通数组和关联数组之间不能转换

普通数组的数组赋值
单个赋值
zhou[0]=”ceo”
数组名为zhou
下标为0
元素是ceo
zhou[1]=”cto”

一次性多个赋值
name=(“mage” “zhangsir” “wang” “zhouyafei”)

引用单个数组
echo ${zhou[0]}
echo ${zhou[1]}

引用多个数组
echo ${name[@]}

echo ${name[*]}

生成数组列表
[root@centos7 ~]#number=({1..10})
[root@centos7 ~]#echo ${number[@]}
1 2 3 4 5 6 7 8 9 10

生成命令数组列表
[root@centos7 ~]#file=(`ls /bin/*.sh`)
[root@centos7 ~]#echo ${file[@]}
/bin/98_createuser.sh /bin/98_guess.sh

生成数组文件列表
[root@centos7 ~]#file=(f{1,2,3}.{ext,log})
[root@centos7 ~]#echo ${file[@]}
f1.ext f1.log f2.ext f2.log f3.ext f3.log
[root@centos7 ~]#

生成稀疏数组
[root@centos7 ~]#name=([0]=mage [2]=wang [4]=zhouyafei )
[root@centos7 ~]#echo ${name[@]}
mage wang zhouyafei

交互式赋值
[root@centos7 ~]#read -a tile
boss ceo cto beijing
[root@centos7 ~]#echo ${tile[@]}
boss ceo cto beijing

关联数组,自定义下标
[root@centos7 ~]#declare -A tile 声明数组
[root@centos7 ~]#tile[“ceo”]=mage 自定义下标ceo
[root@centos7 ~]#tile[“coo”]=wang 自定义下标coo
[root@centos7 ~]#echo ${tile[@]} 显示全部元素
mage wang

unset tile 删除数组

查看数组有多少元素
[root@centos7 ~]#echo ${#tile[@]}
2

个一个数组增加一个元素
[root@centos7 ~]#tile[${tile[*]}]=x 增加一个x的元素
[root@centos7 ~]#echo ${tile[*]}
x mage wang

用脚本判断数组下标的最大值和最小值

#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-11
#FileName: array.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
declare -a rand #声明rand数组
for ((i=0;i<10;i++));do #for循环 变量i初始值是0 小于10 i++ 0小于10循环一次,加1还小于10,循环>在相加
rand[$i]=$RANDOM #设置一个rand数组,$i是下标,$RANDOM生成一个随机数
if [ $i -eq 0 ];then #如果下标$i等于0
max=${rand[$i]} #max最大值等于数组
min=$max #min最小值于max最大值
else #否则
[ $max -lt ${rand[$i]} ] && { max=${rand[$i]};continue; }
# 如果最大值小于数组 则执行amx等于数组并退出本次循环
[ $min -gt ${rand[$i]} ] && min=${rand[$i]}
#如果最小值大于数组,则min等于数组
fi
done
echo all rand is ${rand[*]} #显示数组的所有元素
echo max $max
echo min $min

字符切片
var=`echo {a..z} |tr -d ” “` 设置一个var变量并删除空格
[root@centos7 ~]#echo $var
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@centos7 ~]#var=`echecho ${#var}
26

排除前3个字符,显示后面的字符
[root@centos7 ~]#echo ${var:3}
defghijklmnopqrstuvwxyz

排除前3个字符,显示后4个字符,排除剩下的所有字符
[root@centos7 ~]#echo ${var:3:4}
defg

显示最后3个字符
[root@centos7 ~]#echo ${var: -3}
xyz

排除前3个和后4个,显示中间的字符
[root@centos7 ~]#echo ${var:3: -4}
defghijklmnopqrstuv

取后4个字符,然后跳个最后2个字符,显示前2个字符
[root@centos7 ~]#echo ${var: -4: -2}
wx

字符串处理
[root@centos7 ~]#var=’zhou:!!:17657:0:99999:7:::’ 定义var变量

从左到右查找找到第一个:就停止查找,并显示查找到不包含:后面的字符
[root@centos7 ~]#echo ${var#*:}
!!:17657:0:99999:7:::

贪婪模式,找到最后一:并显示查找到不包含:后面的字符
[root@centos7 ~]#echo ${var##*:}

从右往左查找,找到:就显示不包含:冒号的左面对的字符
[root@centos7 ~]#echo ${var%:*}
zhou:!!:17657:0:99999:7::

贪婪模式,从右往左查找,找到:就显示不包含:冒号的左面对的字符
[root@centos7 ~]#echo ${var%%:*}
zhou

字符串的搜索替代
找到变量里面的9用大P代替
[root@centos7 ~]#echo ${var/9/P}
zhou:!!:17657:0:P9999:7:::

找到变量里面的全部9 全部用大P代替
[root@centos7 ~]#echo ${var//9/P}
zhou:!!:17657:0:PPPPP:7:::

var=’zhou:x:1001:1001:mage:/home/zhou:/bin/bash’
声明变量

搜索z开头的字符用大P代替
[root@centos7 ~]#echo ${var/#z/P}
Phou:x:1001:1001:mage:/home/zhou:/bin/bash

搜索h结尾的字符用大P代替
[root@centos7 ~]#echo ${var/%h/P}
zhou:x:1001:1001:mage:/home/zhou:/bin/basP

删除z字符
[root@centos7 ~]#echo ${var/z}
hou:x:1001:1001:mage:/home/zhou:/bin/bash

删除全部z字符
[root@centos7 ~]#echo ${var//z}
hou:x:1001:1001:mage:/home/hou:/bin/bash

全部替换成大写
[root@centos7 ~]#echo ${var^^}
ZHOU:X:1001:1001:MAGE:/HOME/ZHOU:/BIN/BASH

声明变量
ver=’ZHOU:X:1001:1001:MAGE:/HOME/ZHOU:/BIN/BASH’

全部替换成小写
[root@centos7 ~]#echo ${ver,,}
zhou:x:1001:1001:mage:/home/zhou:/bin/bash

变量赋值
var=${str-expr}
如果变量str没有赋值或者配置那么变量var=expr
如果变量str赋值了但是赋的值是空。那么变量var= 就等于空
如果变量str赋值了并且不是非空,那么变量var=$str

例:hostname=${HOSTNAME-“localhost”}
HOSTNAME 变量有值
[root@centos7 ~]#echo $hostname
www.magedu.com

HOSTNAME=”” 变量的值为空
hostname=${HOSTNAME-“localhost”}
[root@centos7 ~]#echo $hostname 变量为空

unset HOSTNAME 删除变量,变量没有赋值
hostname=${HOSTNAME-“localhost”}
[root@centos7 ~]#echo $hostname
localhost

变量的高级用法-有类型变量
Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令
用于指定变量的类型,两个命令是等价的

declare -r 只读变量
declare -i 定义整数
declare -a 定义普通数组
declare -A 定义关联数组
declare -f 显示函数列表内容
declare -F 只显示函数名不显示函数内容
declare -x 环境变量,全局变量
declare –l var=UPPER 把变量的大写字母存成小写字母
declare –u var=lower 把变量的小写字母存成大写字母

eval命令后跟一个命令, eval会扫描两遍,第一次扫描会扫描后续的命令有没有变量,如果有变量,就将变量替换成他的值。第2次扫描执行命令
例:n=10
[root@centos7 ~]#eval echo {1..$n}
1 2 3 4 5 6 7 8 9 10

变量的间接引用
例:tile=ceo
ceo=mage
通过变量tile把ceo变量里面的mage引用出来

eval echo \$$tile 可以引用出mage

echo ${!tile}

如果想动态生成命令,就将命令放在一个变量里面,用变量间接的执行操作里面的命令
[root@centos7 ~]#CDM=whoami 定义一个变量
[root@centos7 ~]#eval $CDM 第一次扫描把变量CMD变成whoami 然后执行 eval whoami
root

mktemp
创建临时文件
mktemp 生成的文件名是随机的,它有特殊的符号表示有几位
用大写的X表示,至少3位X,每次执行都会生成随机的后3位
例: mktemp /data/tmpXXX

创建临时文件夹
mktemp -d 表示创建临时文件夹
mktemp -d /data/tmpXXXXXX

定义生成的文件或文件夹在哪个目录下
mktemp -p 指定
mktemp -d -p /mnt/ tempXXXXXX

安装复制文件
install可以复制文件并创建文件的属性权限组
install -m 700 -o wang -g bin /etc/shadow /data/passwd.txt
-m 700 权限
-o wang 所有者
-g bin 所有组

install -m 700 -d /data/test
-d 创建文件夹并设置权限
mkdir -m 700 /data/tast

expect工具,独立的语言
常用于自动化的交互场景所有
把执行程序的时候要输入的命令放在脚本里面,当执行程序的时候自动化执行
expect 本身是交互式命令

yum install expect

expect 中相关的命令
spawn:启动新的进程 激活
expect 期望收到某个指令
send 向前面激活的程序发生字符串
intercat 允许用户交互
exp_continue 匹配多个字符串在执行动作后加此命令
例:expect1.1> expect “hi” { send “You said hi\n” } 如果收到hi的指令 就打印You said hi ,默认不会换行要加\n
hi 输入hi
You said hi 显示

scp /etc/fstab root@172.20.109.212:/data/ 远程传输文件
如果ssh传输文件的时候太慢
更改 /etc/ssh/sshd_config 文件
第 79行 GSSAPIAuthentication 把后面的选项改成no
第115行把 UseDNS no 服务前面的#号取消
systemctl restart sshd
启动服务

vim expect.exp

#!/usr/bin/expect
spawn scp /etc/fstab root@172.20.109.212:/data/ #spawn 激活进程
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “123456\n” }
}
expect eof #退出结束

ssh登录自动化,并且可以敲命令
spawn ssh 172.20.109.212 远程登录

#!/usr/bin/expect
spawn ssh 172.20.109.212
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “123456\n” }
}
interact #允许用户交互

也可以设置变量
#!/usr/bin/expect
set ip 172.20.109.212
set user root
set password 123456
spawn ssh $user@$ip
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “$password\n” }
}
interact

位置参数
#!/usr/bin/expect
set ip [lindex $argv 0] # lindex $argv 0 代表第一个参数
set user [lindex $argv 1] #第二个参数
set password [lindex $argv 2] #第三个参数
spawn ssh $user@$ip
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “$password\n” }
}
interact

./expect.exp 172.20.109.212 root 123456 执行命令
写入 ip 用户 密码

如何把一个文件传到100个电脑
先创建一个scp远程传输文件的expect的脚本
vim expect.exp
#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
spawn scp /etc/passwd $user@$ip:/data/
expect {
“yes/no” { send “yes\n”;exp_continue }
“password” { send “$password\n” }
}
expect eof

如果在编辑一个bash的脚本调用expect的脚本
vim expect_exp.sh
#!/bin/bash
#
#********************************************************************
#Author: zhouyafei
#Date: 2018-05-12
#FileName: expect_exp.sh
#Description: The test script
#Copyright (C): 2018 All rights reserved
#********************************************************************
user=root
password=123456
for i in {212..212};do
ip=172.20.109.$i
/root/expect.exp $ip $user $password
done

本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/98537

(0)
上一篇 2018-05-14 20:09
下一篇 2018-05-15 00:39

相关推荐