Shell 一个月时间让你从小白到实战【万字笔记建议收藏方便学习】

🏷️ 365bet娱乐场中文 🕒 2025-07-20 07:06:34 👤 admin 👁️ 3307 ❤️ 413
Shell 一个月时间让你从小白到实战【万字笔记建议收藏方便学习】

作者主页

目录

为什么要学习Shell?

shell变量概述

变量使用

变量定义方式

截取

查看变量

清除变量

变量嵌套

开启新shell 全局变量

系统环境变量

位置参数

预定义变量

shell变量赋值

if比较

for循环

脚本题

变量替换

shell变量运算

流程控制语句

单分支语句

双分支语句

多分支语句

文件比较

与或非格式

流程控制语句-整数比对

流程控制语句-字符对比

正则表达式

流程控制语句-正则比对

case语句

循环语句

批量创建用户

批量探测主机是否存活

随机点名

随机猜数

程序语句

函数与数组

为什么要学习Shell?

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变量概述

变量是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)) #将由里向外运行命令

开启新shell 全局变量

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

shell变量赋值

例: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为真其他为假

if比较

-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循环

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} #替换所有

shell变量运算

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 "删除完成"

case语句

主要用在对菜单的处理。比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

相关文章

九一一袭击事件
365bet娱乐场中文

九一一袭击事件

📅 07-07 👁️ 5938
颀长的意思
365提款一直在处理中

颀长的意思

📅 07-02 👁️ 4394
考公考编学的内容差距大吗?
365bet娱乐场中文

考公考编学的内容差距大吗?

📅 07-16 👁️ 413