目录
为什么要学习Shell?
shell变量概述
变量使用
变量定义方式
截取
查看变量
清除变量
变量嵌套
开启新shell 全局变量
系统环境变量
位置参数
预定义变量
shell变量赋值
if比较
for循环
脚本题
变量替换
shell变量运算
流程控制语句
单分支语句
双分支语句
多分支语句
文件比较
与或非格式
流程控制语句-整数比对
流程控制语句-字符对比
正则表达式
流程控制语句-正则比对
case语句
循环语句
批量创建用户
批量探测主机是否存活
随机点名
随机猜数
程序语句
函数与数组
1、什么是Shell
Shell是一种用户使用的解释型程序,它是操作系统的一部分,派生自多种不同的系统。它是一种命令解释器,它可以读取用户的输入,解释该输入,并执行相应的命令。 Linux的Shell有很多种,如bash,csh,ksh等。当前常用的为bash
2、Shell 的特性
(1)交互式:用户可以通过Shell的界面实现与计算机的交互,以便用户和计算机之间的信息交换。
(2)自动化: Shell 可以将用户编写的一系列命令,保存为脚本,并在需要的时候自.动执行,以减少用户的工作量。
(3)扩展性: Shell 可以实现过滤和管道功能,可以与其他应用程序和编程语言结合使用,实现不同应用程序、不同编程语言之间的信息传递
#!/bin/bash #shell脚本应以此开头
chmod +x test.sh #新脚本完成后需要给予运行权限
#脚本运行方法
./test.sh #用户身份执行
/sh/test.sh #用户身份执行
sh test.sh #管理员身份执行
source test.sh #管理员身份执行
. test.sh #管理员身份执行
变量是shell传递数据的一种方法,即用一个固定的字符串去表示不固定的值,便于后期引用
a=34 #将固定字符a表示为34
echo $a #返回a
34 #返回的执行结果
name="zhangsan" #定义变量
age=19 #定义变量
score=90 #定义变量
id=1 #定义变量
info="ID:$id Name:$name Age:$age Score:$score" #在变量中引用变量
eccho $info #返回info
ID:1 Name:zhangsan Age:19 Score:90 #返回结果
time=$(date +%F) #变量中套用命令
echo $time #返回time
2023-07-25 #返回的执行结果
用户自定义变量:人为定义变量
系统环境变量:系统操作环境相对自带的
位置参数变量:向脚本传递参数的变量
预定义变量:bash定义好的变量
变量名不能出现"-",有空格时需要用引号括起来
var=“hello word”
2.引用变量,$+变量名或者${变量名}
id=1 #定义变量
info="ID:$id" #引用id变量
name=zhangsan #定义name变量
echo "${name}_is" #引用name变量时后缀加_is
zhangsan_is #返回结果
例:
id=1
name=zhangsan
age=19
score=90
student="ID:${id}姓名:${name}年龄:${age}成绩:${score}"
echo $student
ID:1姓名:zhangsan年龄:19成绩:90
ifconfig ens33|head -2|tail -1|awk '{print $2}' #截取ip
df -hT|head -7|tail -1|awk '{print $6}' #截取硬盘使用百分比
used *100 / buff/cache #内存占比公式定义为变量时双嵌套
mem=$((used *100 / buff/cache)) #计算
set |grep ip
unset ip
引用变量,双引号属于弱引用取变量的值,单引号属于强引用原封不动引用变量
echo "$var hello china" #需要引用变量值
echo '$var hello china' #只想引用变量名,不执行$特殊符号
echo "$var hello china \$SHELL" #部分变量执行,部分变量不执行
aa=$(rpm -e $(rpm -qa|grep java)) #将由里向外运行命令
bash #开启一个新的shell,之前设定的所有局部变量将清空
export ip=$(ifconfig ens33|head -2|tail -1|awk '{print $2}')
#变量前加export时变量变为全局变量可在多个shell中使用,不加时默认为局部变量
echo $PATH #PATH路径,系统命令查找路径
/usr/local/bin:/usr/local/sbin:/usr/bin:usr/sbin #PATH返回结果
export PATH=${PATH}:/sh #在PATH中添加路径(重启丢失)
echo "export PATH=${PATH}:/sh" >> /etc/profile #永久追加路径
echo "宿主目录: $HOME"
echo "当前目录: $PWD"
echo "主机名: $HOSTNAME"
echo "客户端地址和端口: $SSH_CONNECTION"
vim variable.sh
#!/bin/bash
echo "当前shell脚本的文件名:$0"
echo "第1个shell脚本位置参数:$1"
echo "第2个shell脚本位置参数:$2"
echo "第3个shell脚本位置参数:$3"
echo "第10个shell脚本位置参数:${10}"
例:
vi test.sh
#!/bin/bash
echo $(($1 + $2))
#
./test.sh 34 56 #34即为$1 56即为$2
90 #返回的值
vi test.sh
#!/bin/bash
echo $1
echo $2
echo $3
echo $4
echo $5
#
./test.sh 23 34 45
23 #返回的值
34 #返回的值
45 #返回的值
echo $* #所有传递的位置参数:
echo $@ #所有传递的位置参数:
echo $# #共传递的参数数量
echo $$ #当前程序运行的PID:
echo $? #返回上一个命令执行的返回结果为0时代表上一个命令成功其他为错误
例
vi test.sh
#!/bin/bash
echo $*
echo $@
#
./test.sh 2 34 535 54 35 345
2 34 535 54 35 345 #返回的值所有传递的位置参数
2 34 535 54 35 345 #返回的值所有传递的位置参数
vi test.sh
#!/bin/bash
echo $#
#
./test.sh 2 34 535 54 35 345
6 #返回的值总共传递的参数数量
vi test.sh
#!/bin/bash
echo $$
#
./test.sh
6667 #返回的值脚本本身pid
例:read -p 交互方式变量赋值
vi test.sh
#!/bin/bash
read -p "请输入第一个值:" num1
read -p "请输入第二个值:" num2
sum=$((num1 + num2))
echo "$num1 + $num2 = $sum"
#执行以上脚本
./test.sh
请输入第一个值:4 #返回结果
请输入第二个值:8 #返回结果
4 + 8 = 12 #返回结果
&> #混合输出将覆盖原文件的信息,&>>将追加至源文件信息后
ping -w1 -c1 baidu.com &> file
cat file
PING baidu.com (110.242.68.66) 56(84) bytes of data. #file文件信息
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=1 ttl=128 time=21.5 ms #file文件信息
#file文件信息
--- baidu.com ping statistics --- #file文件信息
1 packets transmitted, 1 received, 0% packet loss, time 0ms #file文件信息
rtt min/avg/max/mdev = 21.571/21.571/21.571/0.000 ms #file文件信息
ping -c1 -w1 www.baidu.com &> /dev/null #/dev/null为系统自带垃圾箱,放此后会删除
echo $? #返回上一个命令执行的返回结果 0 0为真其他为假
-e 文件名 如果文件存在则为真
-r 文件名 如果文件存在且可读则为真
-w 文件名 如果文件存在且可写则为真
-x 文件名 如果文件存在且可执行则为真
-s 文件名 如果文件存在且至少有一个字符则为真
-d 文件名 如果文件存在且为目录则为真
-f 文件名 如果文件存在且为普通文件则为真
-c 文件名 如果文件存在且为字符型特殊文件则为真
-b 文件名 如果文件存在且为块特殊文件则为真
= 等于则为真
!= 不相等则为真
-z 字符串 字符串的长度为零则为真
-n 字符串 字符串的长度不为零则为真
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-ge 大于等于则为真
-lt 小于则为真
-le 小于等于则为真
例
vi read3.sh
#!/bin/bash
read -p "请输入需要检测的ip地址:"IP
ping -w1 -c1 ${IP} &> /dev/null #-c指定包的数量,-w为等待时间秒为单位 &>:混合输出至 #/dev/null:系统自带垃圾箱
if [ $? -eq 0 ];then #if [];then 条件,then满足时返回
#$? -eq 0 $?返回的值等于0
echo "${IP} 可以通信" #满足$? -eq 0时返回
else #不满足上面条件时
echo "${IP} 无法通信"
fi
for 将要使用的变量名 in 一个数列do
要做的事情
done
#!/bin/bash
read -p "请输入网段:" IP
for i in {1..254}
do
ping -c 1 -w 1 ${IP}.${i} &> /dev/null
if [ $? -eq 0 ];then
echo -e "\033[32m ${IP}.${i}可以通信 \033[0m"
else
echo -e "\033[31m ${IP}.${i}无法通信 \033[0m"
fi
done
在每月第一天备份并压缩/etc目录的所有内容,放到/backup,备份文件以时间戳命名。 (1) 备份目录在哪,/backup (2) 备份目标是谁,/etc (3) 命令,tar (4) 时间戳命名,$(date +%F)
url="www.baidu.com"
echo $url
www.baidu.com #返回的值
echo ${url#*.}
baidu.com #返回的值
${变量#匹配规则} #从头开始匹配,最短删除
${变量##匹配规则} #从头开始匹配,最长删除
${变量%匹配规则} #从尾开始匹配,最短删除
${变量%%匹配规则} #从尾开始匹配,最长删除
${变量/旧字符串/新字符串} #替换字符串,仅替换第一个
${变量//旧字符串/新字符串} #替换字符串,替换全部
例1:从前往后删变量内容
Qh_url=mirrors.tuna.tsinghua.edu.cn
echo $Qh_url #直接返回变量
echo ${Qh_url#*.} #删除.分隔的第一个字段
echo ${Qh_url##*.} #仅保留最后一个字段
例2:从后往前删变量内容
Qh_url=mirrors.tuna.tsinghua.edu.cn
echo $Qh_url
echo ${Qh_url%.*} #删除最后一个字段
echo ${Qh_url%%.*} #仅保留第一个字段
例3:变量内容替换
Qh_url=mirrors.tuna.tsinghua.edu.cn
echo $Qh_url
echo ${Qh_url/u/U} #替换从左往右第一个
echo ${Qh_url//u/U} #替换所有
1.整数运算,expr、$(())、$[],不支持小数运算
a+b 加 a-b 减 a*b 乘(expr计算时,用 \ *) a/b 除 a%b 余
例1:
#只能进行整数之间的运算
a=20
b=10
#运算方式
expr $a + $b
echo $(( $a + $b ))
echo $[ $a + $b ]
例2:递增和递减
#每运行一次对应的数值就加1
echo $((a++))
echo $((a--))
echo $((++b))
echo $((--b))
echo $((100*(1+100)/2)) 求1到100之和
脚本题: 例:查看内存使用率,仅保留整数
#!/bin/bash
Mem_use=$(free -m |grep ^M |awk '{print $3/$2*100}')
if [ ${Mem_use%.*} -ge 80 ];then # -ge 大于等于
echo "memory is overfull: ${Mem_use%.*}%"
else
echo "memory is OK: ${Mem_use%.*}%"
fi
例:查看磁盘使用状态,使用率超出80%就报警 思路: 怎么查看磁盘 怎么提取使用率 整数判断
#!/bin/bash
Disk=$(df -h |grep /$ |awk '{print $(NF-1)}') #NF代表列的数量
if [ ${Disk%\%} -ge 80 ];then
echo "你的磁盘使用率过高:$Disk"
else
echo "你的磁盘使用率正常:$Disk"
fi
if [ 满足条件 ];then
执行代码
fi
#!/bin/bash
if [ while 1>0 ];then #如果1>0
echo "ok"
fi
if [ 满足条件 ];then
执行代码
else #如果上面条件不满足
执行另一条代码
fi
#!/bin/bash
if grep "$1" /etc/passwd;then
echo "ok"
else
echo "error"
fi
if [ 满足条件1 ];then
执行代码1
elif [ 满足条件2 ];then
执行代码2
else #如果以上条件都不满足
执行最后代码
fi
例:
#!/bin/bash
read -p "请输入用户名:" User
if grep $User /etc/passwd &> /dev/null;then
echo "用户$User存在"
elif ls -d /home/$User &> /dev/null;then
echo "用户$User不存在"
echo "但是$User宿主目录存在"
else
echo "用户$User不存在"
echo "$User宿主目录也不存在"
fi
-e 文件或目录是否存在 [ -e file ] -s 文件存在且至少有一个字符则为真 [ -s file ] -d 目录是否存在 [ -d file ] -f 文件是否存在 [ -f file ] -r 文件存在且可读 [ -r file ] -w 文件存在且可写 [ -w file ] -x 文件存在且可执行 [ -x file ]
#!/bin/bash
if [ -e /etc/passwd ];then
echo "/etc/passwd存在"
else
echo "/etc/passwd不存在"
fi
#判断/etc/passwd是否存在
&& #与 1 && 1 = 1 0 && ? = 0 两者同时满足 || #或 1 || ? = 1 0 || 1 = 1 两者满足其一 ! #非 取反 !真 = 假 反之则为真
-eq #等于则为真 [ $? -eq 0 ] -ne #不等则为真 [ $? -ne 0 ] -gt #大于则为真 [ 1 -gt 2 ] -lt #小于则为真 [ 1 -lt 2 ] -ge #大于等于则为真 [ 1 -ge 2 ] -le #小于等于则为真 [ 1 -le 2 ]
例1:监控nginx状态,nginx故障则停止keepalived服务
#!/bin/bash
killall -0 nginx
if [ $? -ne 0 ];then
systemctl stop keepalived
fi
例2:判断服务是否运行
#!/bin/bash
if [ $# -ne 1 ];then
echo "请在运行代码后输入一个服务名称"
exit
fi
systemctl status "$1" &> /dev/null
if [ $? -eq 0 ];then
echo "$1 服务正在运行"
else
echo "$1 服务没有运行"
systemctl restart $1
echo "$1 服务已重新启动"
fi
= 等于则为真 [ "$a" == "$b" ] != 不等则为真 [ ! "$b" == "$a" ] -z 字符长度为零则为真 [ -z "$a" ] -n 字符长度不为零则为真 [ -n "$a" ] str1>str2 str1大于str2则为真 [ str1>str2 ] str1
例
#!/bin/bash
read -p "请输入yes/no:" n
if [ ${n} = "yes" ];then
echo "this is ok"
else
echo "this is no"
fi
#!/bin/bash
read -p "请输入你的分数" fs
expr $fs + 1 &> /dev/null
if [ $? -ne 0 ];then
echo "请输入一个数字"
exit
fi
if [ $fs -ge 0 -a $fs -le 60 ];then
echo "成绩不及格,请补考"
elif [ $fs -gt 60 -a $fs -le 80 ];then
echo "成绩合格"
elif [ $fs -gt 80 -a $fs -le 100 ];then
echo "成绩优秀,恭喜"
else
echo "成绩应在0-100之间"
fi
$ #匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。 ( ) #标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。 * #匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。 + #匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。 . #匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。 ? #匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。 \ #将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。 ^ #匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^。 { #标记限定符表达式的开始。要匹配 {,请使用 \{。 | #指明两项之间的一个选择。要匹配 |,请使用 \|。 限定符: * #匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于 {0,}。 + #匹配前面的子表达式一次或多次。例如,zo+ 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 ? #匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 "do" 、 "does"、 "doxy" 中的 "do" 。? 等价于 {0,1}。 {n} #n 是一个非负整数。匹配确定的 n 次。例如,o{2} 不能匹配 "Bob" 中的 o,但是能匹配 "food" 中的两个 o。 {n,} #n 是一个非负整数。至少匹配n 次。例如,o{2,} 不能匹配 "Bob" 中的 o,但能匹配 "foooood" 中的所有 o。o{1,} 等价于 o+。o{0,} 则等价于 o*。 {n,m} #m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 "fooooood" 中的前三个 o。o{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。x|y #匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food" [xyz] #字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。 #注意!在中括号里面包含 ^ 表示"排除" [^xyz]#负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'、'l'、'i'、'n'。 [a-z] #字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。 \b #匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 \B #匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 \d #匹配一个数字字符。等价于 [0-9]。 \D #匹配一个非数字字符。等价于 [^0-9]。 \s #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 \S #匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 \w #匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。 \W #匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。
举例
^[a-z][0-9]$ #匹配以字母开头,以数字结尾 ^[^0-9][0-9]$ #匹配以非数字开头,以数字结尾 [^a-z] #除了小写字母以外的所有字符 [^\\\/\^] #除了(\)(/)(^)之外的所有字符 [^\"\'] #除了双引号(")和单引号(')之外的所有字符 ^[a-zA-Z_]$ #所有的字母和下划线 _ ^a$ #字母a ^a{4}$ #aaaa ^a{2,4}$ #aa,aaa或aaaa ^a{1,3}$ #a,aa或aaa ^a{2,}$ #包含多于两个a的字符串 ^a{2,} #如:aardvark和aaab,但apple不行 a{2,} #如:baad和aaa,但Nantucket不行 ^[a-zA-Z0-9_]{1,}$ # 所有包含一个以上的字母、数字或下划线的字符串 ^[1-9][0-9]{0,}$ # 所有的正整数 ^\-{0,1}[0-9]{1,}$ # 所有的整数 ^[-]?[0-9]+\.?[0-9]+$ # 所有的浮点数
#判断当前用户是否r开头
[[ "$USER" =~ ^r ]] && echo $?
#判断num变量是否为多个数字
[[ $num =~ ^[0-9]+$ ]]&& echo "成立"||echo "不成立"
脚本创建用户
#!/bin/bash
read -p "请输入用户名前缀:" q
if [[ ! ${q} =~ ^[a-Z]+$ ]];then
echo "前缀应为字母组合"
quit
fi
read -p "请输入用户名后缀(应为数字):" w
if [[ ${w} =~ ^[0-9]+$ ]];then
user=${q}${w}
useradd $user
echo "123456" | passwd --stdin ${user} &> /dev/null
echo "您当前指定的用户名为${user},初始密码为123456"
fi
同时创建多个用户
seq 100 #生成100个序列
#!/bin/bash
read -p "请输入要创建的用户名" name
if [[ $name =~ ^[0-9]+$ ]];then
echo "用户名必须是数字"
exit
fi
read -p "请输入要创建的个数" num
if [[ $num =~ ^[^0-9]+$ ]];then
echo "用户数量必须是数字"
exit
fi
for i in $(seq $num)
do
user=${name}${i}
useradd ${user} &> /dev/null
echo '123' |passwd -stdin ${user} &> /dev/null
done
echo "创建完成,初始密码为123"
read -p "请输入要删除的用户名" name
read -p "请输入数量" num
for i in $(seq ${num})
do
user=${name}${i}
userdel -r ${user} &> /dev/null
done
echo "删除完成"
主要用在对菜单的处理。比if更简单明了,if适合针对一个范围进行判断。case适合等值判断
cat << END
------选项菜单-------
1.----copy-----------
2.----mv-------------
3.----backup---------
---------------------
END
read -p "请输入您的选择" n
case ${n} in
1)
echo "copy"
;;
2)
echo "mv"
;;
3)
echo "backup"
;;
*)
echo "不在菜单内"
;;
esac
案例:服务启动停止脚本
#!/bin/bash
if [ $1 == "start" ];then
rsync --daemon
echo "rsync已启动"
elif [ $1 == "stop" ];then
killall rsync
echo "rsync已关闭"
else
echo "请配合start|stop"
exit
fi
#/var/run/ #程序pid日志文件存储目录
sed -i 's/# pid file/pid file/' /etc/rsyncd.conf #启动rsync的pid配置文件
. /etc/init.d/functions
case $1 in
start)
if [ ! -f /var/run/rsyncd.pid ];then
rsync --daemon
action "rsync running.." /bin/true
else
action "rsync 已启动" /bin/false
fi
;;
stop)
killall rsync
;;
status)
echo "状态"
;;
*)
echo "不在选项内"
;;
esac
举例
case启停nginx
#!/bin/bash
. /etc/init.d/functions
case $1 in
start)
if [ -f /var/run/nginx.pid ];then
action "nginx已在运行状态无法重复运行" /bin/false
else
sudo systemctl start nginx
if [ $? -eq 0 ];then
action "nginx启动成功" /bin/true
else
action "nginx启动失败请检查原因" /bin/false
fi
fi
;;
stop)
if [ -f /var/run/nginx.pid ];then
sudo systemctl stop nginx
if [ $? -eq 0 ];then
action "nginx关闭成功" /bin/true
else
action "nginx关闭失败" /bin/false
fi
else
action "nginx并未在运行" /bin/false
fi
;;
reload)
if [ -f /var/run/nginx.pid ];then
sudo systemctl restart nginx
if [ $? -eq 0 ];then
action "nginx重启成功" /bin/true
else
action "nginx重启失败" /bin/false
fi
else
action "nginx未在运行中,无法进行重启" /bin/false
fi
;;
status)
if [ -f /var/run/nginx.pid ];then
echo "nginx正处于运行状态"
else
echo "nginx现在未在运行"
fi
;;
*)
echo "请输入start|stop|reload|status"
;;
esac
#重新定义分隔符
IFS=
#累加
((i=1;i<=100;i++)) #i的初始值为1,当i小于等于一百,i做累加
#结构
for 变量名 in
do
循环命令语句
done
read -p "请输入最大值" n
for i in $(seq ${n})
do
echo ${i}
done
a=1
b=9
for i in {1..9}
do
let a++
let b--
echo $a:$b
done
echo $((RANDOM)) #生成随机数
echo $((RANDOM))|md5sum #无序乱码随机数
echo $((RANDOM))|md5sum|cut -c 2-10 #截取第二位到第十位
#!/bin/bash
if [! $UID -eq 0 ];then
echo "非管理员无权访问"
exit
fi
read -p "请输入用户前缀" name
read -p "请输入创建数量" num
echo "创建用户${name}1到${name}-${num}"
read -p "确认创建(y/n)" m
case $m in
y)
for i in $(seq $num)
do
user=${name}${i}
id ${user} &> /dev/null
if [ $? -eq 0 ];then
echo "${user}已存在"
else
useradd ${user}
pass=$(echo $((RANDOM))|md5sum|cut -c 2-10)
echo ${pass}|passwd --stdin ${user} $> /dev/null
echo "用户名:${user} 密码:${pass}" >> /sh/user.txt
fi
done
echo "用户已创建完成,信息存放在/sh/user.txt中"
;;
n)
exit
;;
*)
echo "请输入y或n"
;;
esac
#!/bin/bash
for i in $(seq 10)
do
ip=192.168.154.${i}
ping -c 1 -w 1 ${ip} &> /dev/null
if [ $? -eq 0 ];then
echo "${ip} 可到达"
else
echo "${ip}无法到达"
fi
echo ${ip} >> /tmp/ip.txt
done
wait
echo "ping 测试结束,端口测试开始"
for i in $(cat /tmp/ip.txt)
do
nmap ${i} |grep 22 &> /dev/null
if [ $? -eq 0 ];then
echo "${i} 22端口正常"
else
echo "${i} 22端口未检出"
fi
done
echo "测试完成"
#!/bin/bash
#随机数公式,得到1-n范围的随机数
#RANDOM%n+1
#sed -n "1p" student.txt #打印student.txt中的第一行
num=$(wc -l /sh/student.txt|awk '{print $1}')
for i in $(seq ${num})
do
n=$((RANDOM%${num}+1))
sed -n "${n}p" student.txt
sleep 1 #暂停一秒
done
s=$(sed -n "${n}p" student.txt)
echo -e "就是你了:\033[32m $s \033[0m"
while true #无限循环
continue #继续上一次操作
break #退出循环到done后
#!/bin/bash
i=0
num=$((RANDOM%100+1))
while true
do
read -p "请猜一个1-100的数字" s
if [[ $s =~ ^[^0-9]+$ ]];then
echo "输入错误,请输入1-100的纯数字"
continue
fi
if [ $s -gt $num ];then
echo "你猜大了"
elif [ $s -lt $num ];then
echo "你猜小了"
else
echo "你真厉害,猜对了"
break
fi
let i++
done
echo "你总共猜了$(( $i + 1 ))次"
exit #退出程序 break #打断循环执行循环之后的代码 continue #重新开始循环
最后给大家带上函数简单应用以便大家自己去进行拓展
定义函数 命令的集合,用来完成特定的功能; 提前定义函数,在脚本中任意调用函数名。 使用函数使代码模块化,便于重复使用,增加可读性。
#!/bin/bash
#函数定义格式:
#函数名(){
# shell命令
#}
#
#或
#
#function 函数名 {
# shell命令
#}
#定义menu函数内容
#menu(){
#定义菜单时,应贴着左侧写
#cat << END
#1.创建用户
#2.删除用户
#3.退出程序
#END
#}
#调用menu
#menu
menu(){
cat << END
1.创建用户
2.删除用户
3.退出程序
END
}
input(){
while true
do
read -p "请输入用户前缀:" name
if [[ $name =~ [0-9]+ ]];then
echo "前缀不能包含数字"
continue
fi
break
done
while true
do
read -p "请输入用户数量" num
if [[ $num =~ ^[^0-9]+$ ]];then
echo "数量应为数字"
continue
fi
break
done
}
function create {
input
read -p "将创建${name}1~${name}${num} {y/n}" m
case ${m} in
y)
for i in $(seq $num)
do
user=${name}${i}
id ${user} &> /dev/null
if [ $? -eq 0 ];then
echo "用户:${user}已存在"
else
useradd ${user} &> /dev/null
pass=$(echo $((RANDOM))|md5sum|cut -c 2-10)
echo ${pass}|passwd --stdin ${user} &> /dev/null
echo "用户名:${user} 密码:${pass}" >> /tmp/user.txt
echo "${user}创建成功"
fi
sleep 1
done
;;
n)
;;
*)
echo "输入无效应为 y|n"
create
;;
esac
}
while true
do
menu
read -p "请对菜单进行选择(1-3)" y
case $y in
1)
create
;;
2)
echo 删除用户
;;
3)
;;
*)
echo "选择无效,请选择 1|2|3"
;;
esac
done