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

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

流程控制语句

单分支语句

 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<str2   str1小于str2则为真       [ str1<str2 ]

#!/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


目录
相关文章
|
7月前
|
关系型数据库 MySQL Shell
shell学习(十七) 【mysql脚本备份】
shell学习(十七) 【mysql脚本备份】
53 0
|
2月前
|
监控 Unix Shell
shell脚本编程学习
【10月更文挑战第1天】shell脚本编程
81 12
|
6月前
|
移动开发 监控 安全
【实战指南】从零构建嵌入式远程Shell,提升跨地域协作效率
构建嵌入式远程Shell的文章概述: - 目标:解决嵌入式软件测试中的远程调试难题,提供轻量级解决方案。 - 功能:包括远程交互、命令执行与反馈,强调多客户端并发连接和稳定性。 - 设计:基于Socket服务端架构,使用I/O多路复用和popen函数,确保命令执行与结果反馈。 - 需求:支持命令解析、执行和结果回传,考虑网络不稳定情况下的连接保持。 - 安全性:仅限内部调试,未详细讨论加密等安全措施。 - 实现:关注点在Socket服务端程序,包括监听、数据过滤和命令处理。 - 测试:通过 Telnet 和Windows网络助手验证连接和命令执行功能。
336 70
|
5月前
|
Shell Linux
Shell 脚本编程学习
Shell 脚本编程学习
39 0
|
6月前
|
机器学习/深度学习 Unix Java
技术笔记:Linux之Shell脚本编程(一)
技术笔记:Linux之Shell脚本编程(一)
65 0
|
6月前
|
人工智能 运维 中间件
Linux-shell简单学习
Linux-shell简单学习
34 0
|
7月前
|
存储 运维 Java
Linux笔记02 —— Shell补充
Linux笔记02 —— Shell补充
72 2
|
7月前
|
安全 Linux Shell
Linux笔记01 —— Linux初识与Shell汇总(请配合另一篇《Linux笔记02》一起使用)
Linux笔记01 —— Linux初识与Shell汇总(请配合另一篇《Linux笔记02》一起使用)
61 1
|
7月前
|
运维 Shell Python
Shell和Python学习教程总结
Shell和Python学习教程总结
|
7月前
|
机器学习/深度学习 Shell Linux
shell 学习记录
shell 学习记录
36 0