一.函数
shell中允许将一组命令集合或语句形成一段可用代码,这些代码块称为shell函数。给这段代码起个名字称为函数名,后续可以直接调用该段代码的功能。
1.函数定义
函数名()
{
函数体(一堆命令的集合,来实现某个功能)
}
# 可以带function 函数名() 定义,也可以直接 函数名() 定义,不带任何参数
function 函数名()
{
函数体(一堆命令的集合,来实现某个功能)
}
· return说明:
1.return可以结束一个函数,类似于前面讲的循环控制语句break。
2.return默认返回函数中最后一个命令的退出状态,也可以给定参数值,该参数值的范围是0-256之间。
3.如果没有return命令,函数将返回最后一个Shell的退出值。
2.函数调用
2.1 脚本中直接调用
#!/bin/bash
demoFun()
{
echo "这是一个shell函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
2.2 定义到用户的环境变量中
# 当用户打开bash的时候会读取该文件:
/etc/profile --> /etc/bashrc --> ~/.bash_profile --> ~/.bashrc
# 我们可以直接在这些文件中定义函数进行调用
2.3 当前命令行调用
[root@server ~]# cat test.sh
#!/bin/bash
demoFun()
{
echo "这是一个shell函数!"
}
[root@server ~]# source test.sh
[root@server ~]# demoFun
这是一个shell函数!
3.函数传参
#!/bin/bash
funWithParam()
{
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
# 在Shell中,调用函数时可以向其传递参数。
# 在函数体内部,通过 $n 的形式来获取参数的值
案例:让用户输入信息,如果不输入一直提示直到输入
#!/bin/bash
input_fun()
{
input_var=""
output_var=$1
while [ -z $input_var ]
do
read -p "$output_var" input_var
done
echo $input_var
}
#调用函数并且获取用户的姓名、性别、年龄分别赋值给name、sex、age变量
name=$(input_fun 请输入你的姓名:)
sex=$(input_fun 请输入你的性别:)
age=$(input_fun 请输入你的年龄:)
#!/bin/bash
input_fun()
{
read -p "$1" name
if [ -z $name ];then
fun $1
else
echo $name
fi
}
#调用函数并且获取用户的姓名、性别、年龄分别赋值给name、sex、age变量
name=$(input_fun 请输入你的姓名:)
sex=$(input_fun 请输入你的性别:)
age=$(input_fun 请输入你的年龄:)
4.文件包含
和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。
语法格式
. filename #注意点号(.)和文件名中间有一空格
或
source filename
示例
[root@server ~]# cat test1.sh
#!/bin/bash
url="http://www.baidu.com"
[root@server ~]# cat test2.sh
#!/bin/bash
. ./test1.sh
#或者使用以下包含文件代码
#source ./test1.sh
echo "$url"
[root@server ~]# chmod +x test2.sh
[root@server ~]# ./test2.sh
http://www.baidu.com
二.随机数
1.语法结构
# bash默认有一个$RANDOM的变量,默认是0~32767。
set | grep RANDOM
# 查看上一次产生的随机数
echo $RANDOM
# 产生0~1之间的随机数
echo $[$RANDOM%2]
# 产生0~9内的随机数
echo $[$RANDOM%10]
# 产生0~100内的随机数
echo $[$RANDOM%101]
# 产生50-100之内的随机数
echo $[$RANDOM%51+50]
# 产生三位数的随机数
echo $[$RANDOM%900+100]
2.案例
1) 随机产生1000个以182开头的手机号
#!/bin/bash
for ((i=1;i<=1000;i++))
do
n1=$[$RANDOM%10]
n2=$[$RANDOM%10]
n3=$[$RANDOM%10]
n4=$[$RANDOM%10]
n5=$[$RANDOM%10]
n6=$[$RANDOM%10]
n7=$[$RANDOM%10]
n8=$[$RANDOM%10]
echo "182$n1$n2$n3$n4$n5$n6$n7$n8" |tee -a phonenum.txt
done
2) 抽取幸运观众
# 在上面的1000个手机号里抽奖5个幸运观众。
# 显示出这5个幸运观众。
# 只显示头3个数和尾号的4个数,中间用*代替。
#!/bin/bash
phone=phonenum.txt
for ((i=1;i<=5;i++))
do
#统计文件内容的行数
num=`wc -l phonenum.txt |cut -d' ' -f1`
#随机抽取其中的一行
luck_line=`echo $[$RANDOM%$num+1]`
#取出抽取到的幸运行
luck_person=`head -$luck_line $phone |tail -1`
#在源文件中删除该幸运用户,避免二次抽取
sed -i "/$luck_person/d" $phone
echo "幸运观众是:182****${luck_person:7:4}"
done
3) 批量创建5个用户,每个用户的密码为一个随机数
#!/bin/bash
#产生一个保存用户名和密码的文件 (四位随机数)
echo user{1..3}:wang$[$RANDOM%9000+1000] | tr ' ' '\n'>> user_pass.file
# echo user{1..3}:$(pwgen -cn1 12)|tr ' ' '\n'
for ((i=1;i<=5;i++))
do
user=`head -$i user_pass.file|tail -1|cut -d: -f1`
pass=`head -$i user_pass.file|tail -1|cut -d: -f2`
useradd $user
echo $pass|passwd --stdin $user
done
#!/bin/bash
#产生一个保存用户名和密码的文件 (四位随机数)
echo user{1..3}:wang$[$RANDOM%9000+1000] | tr ' ' '\n'>> user_pass.file
# echo user0{1..3}:$(pwgen -cn1 12)|tr ' ' '\n'
for i in `cat user_pass.file`
do
user=`echo $i|cut -d: -f1`
pass=`echo $i|cut -d: -f2`
useradd $user
echo $pass|passwd --stdin $user
done
三.正则表达式
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。
正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。支持正则表达式的程序如:find,vim,grep,sed,awk
- 正则表达式详细可以去参考菜鸟教程
- 70条正则表达式的整理汇总
(1). 任意单个字符,除了换行符
(2)* 前导字符出现0次或连续多次
(3).* 任意长度的字符
(4)^ 行的开头
(5)$ 行的结尾
(6)^$ 空行
(7)[] 匹配指定字符组内的任一单个字符 [abc]
(8)[^] 匹配不在指定字符组内的任一字符 [^abc]
(9)^[] 匹配以指定字符组内的任一字符开头 ^[abc]
(10)^[^] 匹配不以指定字符组内的任一字符开头 ^[^abc]
扩展正则
+ 匹配一个或多个前导字符
? 匹配零个或一个前导字符
a|b 匹配a或b
() 组字符 hello myself yourself (my|your)self
{n} 前导字符重复n次
{n,} 前导字符重复至少n次
{n,m} 前导字符重复n到m次
四.补充
1.shift
shift:使位置参数向左移动,默认移动1位
#!/bin/bash
# 这个脚本可以实现 将脚本后所有的参数的和
sum=0
while [ $# -ne 0 ]
do
let sum=$sum+$1
shift
done
echo sum=$sum
2.expect自动应答
#!/usr/bin/expect
#设置变量
set ip 10.1.1.1
set pass 123456
set timeout 5
#spawn是给后面的运行进程加个壳,用来传递交互指令
spawn ssh root@$ip
#expect用于判断交互中上次输出的结果里是否包含某些字符串
expect {
#exp_continue附加在某个expect判断项之后,使该项匹配后继续匹配其他项
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$pass\r" }
}
expect "#"
#send用于执行交互动作,与手工输入动作等效
send "rm -rf /tmp/*\r"
send "touch /tmp/file{1..3}\r"
send "date\r"
send "exit\r"
expect eof