shell-函数、数组、正则

expect

ssh远程脚本

expect非交互式

脚本代码如下:

#!/usr/bin/expect
set timeout 30
spawn ssh -l root 192.168.1.1
expect "(yes/no)"?
send "yes\r"
expect "password:"
send "123\r"
interact

1.[#!/usr/bin/expect]

这一行告诉操作系统脚本里的代码使用那一个shell来执行。这里的expect其实和Linux下的bash,Windows下的cmd是一类东西。

注意:这一行要放在脚本的第一行。

2.[set timeout 30]

基本上认识英文的都知道这个事设置超时时间的,单位是:秒

3.[spawn ssh -l root 192.168.1.1]

spawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的shell中是找不到spawn命令的。

它主要的功能是给ssh运行的进程加个壳,用来传递交互指令

4.[expect "password:"]

这里的expect也是expect的一个内部命令,expect的shell命令和内部命令四一样的,但不是一个功能,这个命令的意思四判断上次输出结果里是否包含“password:”的字符串,如果有立即返回,否则就等待30秒后返回

5.[send "123\r"]

这里就是执行交互式操作,与手工输入密码的动作等效。命令字符串结尾必须加上“\r”;

6.[interact]

执行完成之后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成之后就会推出,而不是留在远程终端,如果你只是登录过去执行一段命令就退出,可以改为[expect eof]

#!/usr/bin/expect
set timeout 10
spawn ssh -l root 192.168.251.106
#expect "?yes/no??"
#send "yes\r"
expect "password:"
send "123\r"
expect "#"
send "touch /tmp/file1\r"
expect eof

shell脚本嵌套expect

#!/bin/bash
pass=123
/usr/bin/expect <<EOF
set timeout 10
spawn ssh -l root 192.168.251.106
expect "password:"
send "$pass\r"
expect "#"
send "touch /tmp/file1\r"
expect eof
EOF
tput 命令
tput 可以操作光标,定位光标
tput sc 保存光标位置
tput rc 返回光标位置
tput cols 读取列数
tput lines 读取行数
tput cup lines cols 
tput civis # 光标不可见
tput cnorm # 光标可见

定位倒计时

#!/bin/bash
col=`tput cols`
line=`tput lines`
ncol=$(($col/2))
nline=$(($line/2))
tput sc 爆炸
for i in {1..1000}
do
    usleep $i
    tput cup $nline $ncol
    echo "$i"
done
tput cup $nline $ncol
echo "爆炸"
for i in {1..10}
do
    usleep 100000
echo -e "\a"
done
tput rc

shell函数function

函数就是保存好的程序块,如果多条语句需要重复调用,可以定义成函数,可以将函数看作是脚本中的一段代码,但是哟一个主要的区别。执行函数时,它保留当前shell和内存信息。

如果执行或者调用一个脚本中的另一段代码,将创建一个单独的shell,因而去除所有原脚本中定义的存在变量。函数可以放在同一个文件中作为一段代码,也可以放在只包含函数的单独文件中。

在系统中定义的函数库,就是将很多功能预先定义在了一起

[root@localhost test]# cat func.sh 
a=111
b=222
echo $a
echo $b
[root@localhost test]# ./func.sh 
111
222
[root@localhost test]# 

在代码的复用性可维护性方面,函数有着巨大的优势,因此,唱吧功能封装成函数是一件平常的事情,在shell中定义函数的方法如下:

# func_name 函数名
function func_name(){
    # 函数体内容
    }
或
func_name 函数名
func_name(){
    # 函数体内容
    }

系统中这样的情况更加常见,关键变量的定义,关键函数的定义,将事先定义好的东西加载到进程。例如,服务启动成功提示绿色的OK

函数可以直接在命令行设置并使用

[root@localhost test]# func(){ echo hello; echo ok;}
[root@localhost test]# func
hello
ok
[root@localhost test]# 

函数内部定义的变量假如不想让外部访问,可以加上local关键字

函数传参

给函数传递参数

[root@localhost test]# vim sum.sh
[root@localhost test]# chmod 777 sum.sh 
[root@localhost test]# vim sum.sh 
[root@localhost test]# ./sum.sh 
30
[root@localhost test]# cat sum.sh 
#!/bin/bash
sum(){
echo $(($1+$2))
}
sum 10 20
[root@localhost test]# 

shell里的函数和python里的函数都是差不多的,只有个别语法的差异,变量名尽量有意义

 shell数组array

数组是具有相同的数据类型并且按照一定次序排列的一组变量的集合体,构成一个数组的这些变量称为数组元素。

数据在其他编程语言里有一定的含义,数据就像是变量一样,比如要给100个变量赋值,你可能需要些100个变量的名称,但是如果采用数组的情况下,采用一个变量名称就可以了。

严格的写法

[root@localhost test]# declare -a myarray=(1 2 3 4 5)
[root@localhost test]# echo ${myarray[2]}
3

显示所有数组的参数

[root@localhost test]# declare -p myarray
declare -a myarray='([0]="1" [1]="2" [2]="3" [3]="4" [4]="5")'
[root@localhost test]# 

查看数组中的所有元素

[root@localhost test]# echo ${myarray[*]}
1 2 3 4 5
[root@localhost test]# echo ${myarray[@]}
1 2 3 4 5
[root@localhost test]# 

统计数组中的元素的个数

[root@localhost test]# echo ${#myarray[@]}
5
[root@localhost test]# echo ${#myarray[*]}
5
[root@localhost test]# 

统计某个元素中字符的个数

[root@localhost test]# echo ${#myarray[2]}
1
[root@localhost test]# 

删除:

[root@localhost test]# myarray=(1 2 3 4 5)
[root@localhost test]# unset myarray[1]
[root@localhost test]# echo ${myarray[*]}
1 3 4 5
[root@localhost test]# 

特殊使用

分片:

[root@localhost test]# echo ${a[@]:0:3}
1 2 3
[root@localhost test]# echo ${a[@]:1:4}
2 3 4 5
[root@localhost test]# 

直接通过${数组名[@或*]:起始位置:长度} 切片原先的数组,返回是字符串,中间用“空格”分开,因此如果加上“()”,将得到切片数组

替换:

[root@localhost test]# echo ${a[@]/3/100}
1 2 100 4 5
[root@localhost test]# echo ${a[@]}
1 2 3 4 5
[root@localhost test]# 

调用方法是:${数组名[@或*]/查找字符/替换字符} 该操作不会改变原先数据的内容

索引数组

索引数组,即通常情况下所说的数组

[root@localhost test]# declare -a myarray=(1 2 3 4 5)
[root@localhost test]# echo ${myarray[0]}
1
[root@localhost test]# echo ${myarray[2]}
3
[root@localhost test]# 

关联数组

关联数组,指以非序列类型为下标存取的数组,python中叫做字典

[root@localhost test]# declare -A arr
[root@localhost test]# arr["one"]=1
[root@localhost test]# arr["two"]=2
[root@localhost test]# echo ${arr[two]}
2
[root@localhost test]# 

遍历数组

遍历数组

遍历(for循环法)

[root@localhost test]# for var in ${arr[@]}; do echo $var;done
1
2
[root@localhost test]# 

遍历(数组带下标)

[root@localhost test]# for var in ${!arr[@]}; do printf "%s\t%s\n" "$var" "${arr[$var]}";done
one    1two    2
[root@localhost test]# 

遍历(while 循环)

#!/bin/bash
declare -a myarry=(1 2 3 4 5)
i=0
while [ $i -lt ${#myarry[@]} ]
do
echo ${myarry[$i]}
let i++
done

 正则表达式RE

正则表达式分为三类(basic RegExs,extended RegExs,Perl RegExs)

一、正则表达式分类:

1、基本的正则表达式(Basic RegExs,简称BREs)
2、扩展的正则表达式(Extended Regular Expression,简称EREs)
3、Perl的正则表达式(Perl Regular Expression,简称PREs)

二、Linux中常用文本工具与只给你这表达式的关系

1.grep支持:BREs,EREs,PREs正则表达式
    grep指令后不跟任何参数,表示要使用“BREs”
    grep指令后跟“-E”参数,则表示要使用“EREs”
    grep指令后跟“-P”参数,则表示要使用“PREs”
2.egrep支持:EREs,PREs正则表达式
    egrep指令后不跟任何参数,则表示要使用“EREs”
    egrep指令后跟“-P”参数,则表示要使用“PREs”
sed正则表达式特点
  sed文本工具支持:BREs,EREs
  sed指令默认是使用“BREs”
  sed命令参数“-r”,则表示要使用“EREs”

Awk(gawk)正则表达式特点
  Awk文本工具支持EREs
  awk指令默认是使用“EREs”
[root@localhost test]# vim z.txt
[root@localhost test]# cat z.txt 
123 ABC 123
123 ADC 123
123 AER 123
[root@localhost test]# grep A.C z.txt 
123 ABC 123
123 ADC 123
[root@localhost test]# 
[root@localhost test]# vim a.txt
[root@localhost test]# cat a.txt 
a
ab
ac
abb
abc
abbc
abbbbbbbbc
[root@localhost test]# grep ab* a.txt 
a
ab
ac
abb
abc
abbc
abbbbbbbbc
[root@localhost test]# grep ab*c a.txt 
ac
abc
abbc
abbbbbbbbc
[root@localhost test]# grep a* a.txt 
[root@localhost test]# grep a* a.txt 
[root@localhost test]# vim c.txt
[root@localhost test]# cat c.txt 
acc
a.c
a2c
a6c
a/c
a9c
[root@localhost test]# grep a[6789]c c.txt 
a6c
a9c
[root@localhost test]# grep a[1-9]c c.txt 
a2c
a6c
a9c
[root@localhost test]# grep a[^1-9] c.txt 
acc
a.c
a/c
[root@localhost test]# grep a[-+*/]c c.txt 
a/c
[root@localhost test]# 

扩展元字符

+ 匹配前面的正则表达式的一次出现或者是多次出现
? 前边的字符出现0次或者1次
{n, m} 匹配出现的次数是n到m次
{n}匹配出现n次
{n,}匹配至少出现n次

 正则案例:

1,验证用户名跟密码:(“^[A-Za-z0-9]\w{5,15}$”)

2.验证电话号码:(“^(\d{3,4}-)\d{7,8}$”)

3.验证手机号码:("^1[3|4|5|7|8][0-9]\d{8}")

4.验证身份证号码:(“\d{14}[0-9],0-9xX”)

5.验证email地址:(“^\w+([-+.]\w)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$”)

 

6.只能输入有数字和26个英文字母组成的字符串:(“^[A-Za-z0-9]+$”)

 

7.整数或者是小数:(“^[0-9]+([.][0-9]+){0,1}$”)

 

8.只能输入数字:(“^[0-9]*$”)

 

9.只能输入n位的数字:(“^\d{n}$”)

 

10.只能输入至少n位的数字:(“^\d{n,}$”)

11.只能输入m~n位的数字:(“^\d{m,n}$”)

 

12.只能输入零和非零开头的数字:(“^(0|[1-9][0-9]*)$”)

 

13.只能输入有两位小数的正实数:(“^[0-9]+(\.[0-9]{2})?$”)

 

14.只能输入有1~3位小数的正实数:("^[0-9]+(\.[0-9]{1,3})?$")

15.只能输入非零的正整数:(“^\+?[1-9][0-9]*$”)

 

16.只能输入非零的负整数:(“^\-[1-9][0-9]*$”)

17.只能输入长度为3的字符:(“^.{3}$”)

 

18.只能输入由26个英文字母组成的字符串:(“^[A-Za-z]+$”)

 

19.只能输入由26个大写字母组成的字符串:(“^[A-Z]+$”)

 

20.只能输入由26个小写字母组成的字符串:(“^[a-z]+$”)

 

21.验证是否含有^%&',;=?$\等特殊字符:(“[%$*&',;=?\\^]+”)

 

22.验证一年的12个月:(“^(0?[1-9]|1[0-2])$”)

23.验证一个月的31天:(“^((0?[1-9])|((1|2)[0-9])|30|31)$”)

 

24.获取日期的正则表达式:(“\\d{4}[年|\-|\.]\d{\1-\12}[月|\-|\.]\d{\1-\31}日?”)

 

25.匹配空白行的正则表达式:(“\n\s*\r”)

 

 26.匹配url的正则表达式:(“[a-zA-Z]+:\/\/[^\s]*”)

 

27.匹配IP地址:(“([0-9]{1,3}\.){3}[0-9]”)

 

28.匹配MAC地址:(“([A-Fa-f0-9]{2}\:){5}[A-Fa-f0-9]”)

 

正则表达式在线测试工具:超好用https://regexper.com/

 

 

更多请自行百度。。

 

posted @ 2018-09-05 09:14 前方、有光 阅读(...) 评论(...) 编辑 收藏