目录
1、随机数
1、如何生成随机数
RANDOM,随机会产生0-32767的随机整数
产生一个随机数
[root@localhost ~]# echo $RANDOM
13214
产生0-10之间的随机数,只需要取余11
[root@localhost shellDemo]# echo $[RANDOM%11]
6
产生1-50之间的随机数
[root@localhost ~]# echo $[RANDOM%50+1]
35
产生10-99之间的随机数
[root@localhost ~]# echo $[RANDOM%90+10]
98
产生100-999的随机数
[root@localhost ~]# echo $[RANDOM%900+100]
914
产生50-100的随机数
[root@localhost ~]# echo $[RANDOM%51+50]
2、随机产生以139开头的电话号码
#! /bin/env bash
# 产生1000个以139开头的电话号码并保存文件phonenum.txt中
#文件值
file=/root/shellDemo/phonenum.txt
#循环
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 "139$n1$n2$n3$n4$n5$n6$n7$n8" >> $file
done
3、随机抽出5位幸运观众
具体需求:
- 在上面的1000个手机号里抽奖5个幸运观众,显示出这5个幸运观众。
- 但只显示头3个数和尾号的4个数,中间的都用*代替
① 思路
- 确定幸运观众所在的行
0-1000 随机找出一个数字 $[$RANDOM%1000+1]
- 将电话号码提取出来
head -随机产生行号 phonenum.txt |tail -1
-
显示前3个和后4个数到屏幕
echo 139****
② 落地实现
#! /bin/env bash
# 随机抽取2个幸运观众,并显示出来
#获取幸运观众个数
n=$1
#定义变量
phone=/root/shellDemo/phonenum.txt
#循环
for((i=1;i<=$n;i++))
do
#确定文件行数,命令执行结果赋值给变量需要使用``包起命令来
line=`wc -l $phone |cut -d ' ' -f1`
#产生1-line之间的随机数
num=$[RANDOM%$line+1]
#将电话号码提取出来
luck_num=`head -$num $phone |tail -1`
#显示到屏幕,从第8位开始,截取4位,索引从0开始
echo "139****${luck_num:7:4}"
echo $luck_num >> luck.txt
#删除已经被抽取的幸运观众
sed -i "/$luck_num/d" $phone
done
[root@localhost shellDemo]# ./randomdemo2.sh 5
139****9240
139****2506
139****0196
139****5403
139****6964
139****2316
#抽一次删除一次
[root@localhost shellDemo]# wc -l phonenum.txt
1000 phonenum.txt
4、批量创建用户(密码随机产生)
**需求:**批量创建5个用户,每个用户的密码为一个随机数
① 思路
- 循环5次创建用户
- 产生一个密码文件来保存用户的随机密码
- 从密码文件中取出随机密码赋值给用户
② 落地实现
#!/bin/env bash
#crate user and set passwd
#产生一个保存用户名和密码的文件
echo user0{1..5}:itcast$[$RANDOM%9000+1000]#@~|tr ' ' '\n'>> user_pass.file
#循环创建5个用户
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
2 、嵌套循环
循环嵌套就是外层循环一次,内层循环一轮。
1、打印指定图案
#!/bin/env bash
for((i=1;i<=5;i++))
do
for((x=1;x<=$i;x++))
do
#-n表示不换行输出
echo -n $x
done
#换行
echo
done
结果:
1
12
123
1234
12345
3、影响shell程序的内置命令
exit 退出整个程序
break 结束当前循环
continue 跳过本次循环
shift 使位置参数向左移动,默认移动一位,可以使用shift 2
举例说明:
以下脚本都能够实现用户自定义输入数字,然后脚本计算和:
[root@MissHou shell04]# cat shift.sh
#!/bin/bash
sum=0
while [ $# -ne 0 ]
do
let sum=$sum+$1
#使位置参数向左移动 显示参数1,然后参数2下向左移动一位
shift
done
echo sum=$sum
./shift.sh 1 2 3
6
[root@MissHou shell04]# cat for3.sh
#!/bin/bash
sum=0
# for循环的一种语法结构
for i
do
let sum=$sum+$i
done
echo sum=$sum
./for3.sh 1 2 3
6
4、expect
expect自动应答,tcl语言,是一门语言。
https://www.cnblogs.com/zhengbin/p/8872836.html
安装:yum -y install expect
例子1::远程登录到另一个服务器上什么都不做,exit退出
[root@localhost shellDemo]# cat expect.sh
#!/usr/bin/env expect
#开启一个程序,开启会话,接下来通过 expect ... send 来执行交互操作
spawn ssh root@192.168.169.128
#expect期望输出的字符串,send发送交互字符串,回车为 /n,注意空格
# 捕获相关内容 \r表示回车,exp_continue如果没有上一个,继续往下执行
expect {
"(yes/no)?" { send "yes\r";exp_continue }
"password:" { send "12345678\r" }
}
#交互
interact
使用位置参数:
#!/usr/bin/expect
set ip [ lindex $argv 0 ]
set pass [ lindex $argv 1 ]
set timeout 5
spawn ssh root@$ip
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$pass\r" }
}
interact
执行脚本:
[root@localhost shellDemo]# ./expect.sh 192.168.169.128 12345678
例子2::远程登录到另一个服务器上做一些事情,exit退出
#!/usr/bin/expect
set ip [ lindex $argv 0 ]
set pass [ lindex $argv 1 ]
set timeout 5
spawn ssh root@$ip
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$pass\r" }
}
#看到#号就做一些事
expect "#"
#删除目录里a,并回车
send "rm -rf /root/a\r"
#删除完目录,我还想看看主机名
send "hostname\r"
#再打一个日期看看
send "date +%F\r"
#结束程序,等待结束执行,若没有该结束符,脚本可能没有执行完毕就提前退出了
expect eof
执行脚本:
[root@localhost shellDemo]# ./expect.sh 192.168.169.128 12345678
例子3:shell脚本和expect结合使用,在多台服务器上创建1个用户
#!/bin/bash
# 循环在指定的服务器上创建用户和文件
#循环的从文件ip.txt中获取ip和密码
while read ip pass
do
#/usr/bin/expect 脚本中首先引入解释文件,表明使用哪种 shell 解释器
# <<-END表示遇到END,结束,这是shell的here文档,-表示END前面允许有制表符,这里不一定要写END,自定义的,一个字符而已
#如果中途有一些输出全不要,丢到&>/dev/null中
/usr/bin/expect <<-END
#开启一个程序
spawn ssh root@$ip
expect {
"(yes/no)?" { send "yes\r";exp_continue }
"password:" { send "$pass\r" }
}
#期望看到#,如果看到就创建一个用户,删除一些东西,然后退出远程服务器
expect "#" { send "useradd yy1;rm -rf /tmp/*;exit\r" }
#结束程序
expect eof
END
echo "$ip服务器用户创建完毕!"
done < ip.txt
远程服务器查看用户是否创建成功
[root@localhost ~]# id yy1
uid=1001(yy1) gid=1001(yy1) 组=1001(yy1)
例子4:将跳板机上运维用户的公钥推送搭配局域网内可以ping通的所有机器上
跳板机,就是可以给你远程连接的机器,然后通过这个机器再去访问别的机器,
5、sudo简单介绍
给一个账号授予一些权限。
visudo
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
yunwei ALL=(root) NOPASSWD:ALL,!/sbin/shutdown,!/sbin/init,!/bin/rm -rf /
解释说明:
1)第一个字段yunwei指定的是用户:可以是用户名,也可以是别名。每个用户设置一行,多个用户设置多行,也可以将多个用户设置成一个别名后再进行设置。
2)第二个字段ALL指定的是用户所在的主机:可以是ip,也可以是主机名,表示该sudo设置只在该主机上生效,ALL表示在所有主机上都生效!限制的一般都是本机,也就是限制使用这个文件的主机;一般都指定为"ALL"表示所有的主机,不管文件拷到那里都可以用。比如:10.1.1.1=...则表示只在当前主机生效。
3)第三个字段(root)括号里指定的也是用户:指定以什么用户身份执行sudo,即使用sudo后可以享有所有root账号下的权限。如果要排除个别用户,可以在括号内设置,比如ALL=(ALL,!oracle,!pos)。
4)第四个字段ALL指定的是执行的命令:即使用sudo后可以执行所有的命令。除了关机和删除根内容以外;也可以设置别名。NOPASSWD: ALL表示使用sudo的不需要输入密码。
5)也可以授权给一个用户组
%admin ALL=(ALL) ALL 表示admin组里的所有成员可以在任何主机上以任何用户身份执行任何命令
6、数组定义
数组分类:
- 普通数组:只能使用整数作为数组索引
- 关联索引:可以使用字符串作为数组索引
普通数组定义:
一次赋予一个值
数组名[索引下标]=值
array[0]=v0
array[1]=v1
array[2]=v2
一次赋予多个值:
数组名=(v1 v2 v3...)
names=(a b c d)
也可以是一个命令的输出
array1=(`cat 1.txt`)
array2=(`ls /root`)
查看普通数组:
获取指定的元素
[root@localhost shellDemo]# echo ${array1[3]}
world
获取所有元素
[root@localhost shellDemo]# echo ${array1[*]}
hello world hello world
获取数组长度
[root@localhost shellDemo]# echo ${#array1[*]}
4
获取数组元素的索引下标
[root@localhost shellDemo]# echo ${!array1[@]}
0 1 2 3
获取部分元素
[root@localhost shellDemo]# echo ${array1[*]:1:3}
world hello world
查看数组信息
[root@localhost shellDemo]# declare -a
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='()'
declare -a BASH_SOURCE='()'
declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='()'
declare -a GROUPS='()'
declare -a PIPESTATUS='([0]="0")'
declare -a array='([0]="harry" [1]="jack" [5]="jackaaa")'
declare -a array1='([0]="hello" [1]="world" [2]="hello" [3]="world")'
declare -a names='([0]="a" [1]="b" [2]="c" [3]="d")
关联数组定义:
[root@localhost shellDemo]# declare -A asso_array1
[root@localhost shellDemo]# asso_array1[linux]=1
[root@localhost shellDemo]# asso_array1[java]=2
[root@localhost shellDemo]# asso_array1=([php]=3 [python]=4 [go]=5)
[root@localhost shellDemo]# let asso_array1[linux]++
查看关联数组:
获取指定的元素
[root@localhost shellDemo]# echo ${asso_array1[go]}
5
打印数组的所有元素
[root@localhost shellDemo]# echo ${asso_array1[*]}
2 1
打印数组的索引
[root@localhost shellDemo]# echo ${!asso_array1[*]}
java linux
查看关联数组信息
[root@localhost shellDemo]# declare -A
declare -A BASH_ALIASES='()'
declare -A BASH_CMDS='()'
declare -A asso_array1='([java]="2" [linux]="1" )'
使用例子:写一个脚本,统计web服务的不同链接状态个数
7、其他变量定义
变量内容的删出和替换:
去除一个目录下的目录和文件: