shell脚本--学习笔记

shell脚本--学习笔记

shell脚本第一天

1.常用的命令





2.vi /vim

需求1:批量注释前几行 1-10行

:1,10s/^/#/g   注释1-10行
:1,10s/#//g     取消注释





#root:x:0:0:root:/root:/bin/bash
#bin:x:1:1:bin:/bin:/sbin/nologin
#daemon:x:2:2:daemon:/sbin:/sbin/nologin
#adm:x:3:4:adm:/var/adm:/sbin/nologin
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#sync:x:5:0:sync:/sbin:/bin/sync
#shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
#halt:x:7:0:halt:/sbin:/sbin/halt
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin


3.四剑客命令



find   awk    grep    sed


4.如何学好编程
变量


表达式


if



for循环



while循环



case语句



数组



能看懂

能模仿

懂语法




学习方式     

看书


详细笔记

看视频









5.shell入门

shell :命令解释器  负责翻译我们输入的命令  执行ok   返回给用户

命令的堆集就是脚本










6.会python还要学习shell?学了shell还要学python?
python:
自动化工具
自动化平台





shell:
批量  减少重复工作  提升工作效率  









shell脚本第二天


1.变量值的定义
数值的定义
name_age=1231231     必须连续的数字

2.字符串的定义
name="oldboy"     字符串需加双引号,不知道加什么就加双引号  解析变量
                    '' 单引号  所见即所得  吃什么拉什么
                    
                    
3.                    
命令的定义
time=`date`         反引号解析命令
time=$()            $()解析命令



注意命令的定义  是把结果复制给了变量   如果想改变结果  再次赋值

[root@tomcat backup]# time=`date`
[root@tomcat backup]# echo $time 
Tue Apr 2 19:35:07 CST 2024



4.shell特殊位置变量
$0  代表了脚本的名称   如果全路径执行  则脚本名称带全路径    -----常用

使用方法:给用户提示  
    echo $"Usage: $0 {start|stop|status|restart|force-reload}"
了解  只获取脚本名称
[root@tomcat backup]# basename 1.sh 
1.sh
[root@tomcat backup]# basename /backup/1.sh 
1.sh


$n 脚本的第n个参数 0被脚本名称占用 从1开始  $1 $2 $9后面的参数需要加{}
[root@tomcat backup]# bash 1.sh {1..10}
1 2 3 4 5 6 7 8 9 10 11
[root@tomcat backup]# bash 1.sh {a..z}
a b c d e f g h i a0 a1

[root@tomcat backup]# cat 1.sh 
#!/bin/bash
#Author nwq
#test
#QQ
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}

[root@tomcat backup]# bash 1.sh 

[root@tomcat backup]# bash 1.sh {a..z}
a b c d e f g h i j k






$# 获取脚本传参的总个数                               ---常用
[ $# -ne 2 ] && echo "请输入两个参数" && exit


[root@tomcat backup]# cat 1.sh 
#!/bin/bash
#Author nwq
#test
#QQ
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
echo $#
[root@tomcat backup]# bash 1.sh {a..z}
a b c d e f g h i j k
26



扩展:定义只能输入两个传参,不能多,不能少,多或少都不执行,直接退出,并提示
[root@tomcat backup]# cat 1.sh 
#!/bin/bash
#Author nwq
#test
#QQ
[ $# -ne 2 ] && echo "请输入两个参数" && exit
echo $#
name=$1
age=$2
echo $name $age

[root@tomcat backup]# sh 1.sh oldboy
请输入两个参数
[root@tomcat backup]# sh 1.sh oldboy 12 hdn
请输入两个参数
[root@tomcat backup]# sh 1.sh oldboy 12 
2
oldboy 12




$* 获取脚本所有的参数 不加引号和$@相同 加上双引号 则把参数视为一个参数 
$1$2$3 

$@ 获取脚本所有的参数  不加双引号和$*相同,加上双引号则把参数视为独立的参数
$1 $2 $3


------不加双引号
[root@tomcat backup]# cat 1.sh 
#!/bin/bash
#Author nwq
#test
#QQ
name=$1
age=$2
echo $name $age
echo $*
echo $@
[root@tomcat backup]# sh 1.sh oldboy 122 liniu
oldboy 122
oldboy 122 liniu
oldboy 122 liniu

--------加双引号
[root@tomcat backup]# cat 1.sh 
#!/bin/bash
#Author nwq
#test
#QQ
name=$1
age=$2
echo $name $age
echo "$*"
echo "$@"
[root@tomcat backup]# sh 1.sh oldboy 199 lili
oldboy 199
oldboy 199 lili
oldboy 199 lili




区别:$*和$@在脚本中相同,再循环体内不同


[root@tomcat backup]# set -- "i am" nwq teacher
[root@tomcat backup]# echo $*
i am nwq teacher
[root@tomcat backup]# echo $@
i am nwq teacher

[root@tomcat backup]# echo "$*"
i am nwq teacher
[root@tomcat backup]# echo "$@"
i am nwq teacher


[root@tomcat backup]# for i in $*;do echo $i;done
i
am
nwq
teacher
[root@tomcat backup]# for i in $@;do echo $i;done
i
am
nwq
teacher

[root@tomcat backup]# for i in "$*";do echo $i;done
i am nwq teacher
[root@tomcat backup]# for i in "$@";do echo $i;done
i am
nwq
teacher



$?  获取上一条命令的返回结果  0为成功  非0失败 可指定返回结果    ----常用

echo $?
[ $# -ne 2 ] && echo "请输入两个参数" && exit 50


[root@tomcat backup]# cat 1.sh 
#!/bin/bash
#Author nwq
#test
#QQ
[ $# -ne 2 ] && echo "请输入两个参数" && exit 50
name=$1
age=$2
echo $name $age
echo "$*"
echo "$@"

[root@tomcat backup]# sh 1.sh oldboy 14 liniu
请输入两个参数
[root@tomcat backup]# echo $?
50



$$ 获取脚本的PID 


[root@tomcat backup]# cat 1.sh 
#!/bin/bash
#Author nwq
#test
#QQ
name=$1
age=$2
echo $name $age
echo "$*"
echo "$@"
echo $$
[root@tomcat backup]# sh 1.sh 



1699


延长退出时间 
[root@tomcat backup]# cat 1.sh 
#!/bin/bash
#Author nwq
#test
#QQ
name=$1
age=$2
echo $name $age
echo "$*"
echo "$@"
echo $$
sleep 60

追加PID到文件日志里
echo $$ > /tmp/nginx_log.pid

pkill -9 `cat /tmp/nginx_log.pid`










$!  获取上一个在后台运行的脚本的PID 调试使用




$_ 获取命令行最后一个参数
[root@tomcat backup]# ls /etc/passwd
/etc/passwd
[root@tomcat backup]# echo $_
/etc/passwd
[root@tomcat backup]# ll /etc/passwd /etc/hosts
hosts        hosts.allow  hosts.deny   
[root@tomcat backup]# ll /etc/passwd /etc/hosts /etc/resolv.conf 
-rw-r--r-- 1 root root  210 Apr  1 22:48 /etc/hosts
-rw-r--r-- 1 root root 1144 Apr  2 12:33 /etc/passwd
-rw-r--r-- 1 root root  149 Apr  2 15:06 /etc/resolv.conf
[root@tomcat backup]# echo $_
/etc/resolv.conf






常用参数-(必知)

$?   获取上一条命令的返回结果  0为成功  非0失败 可指定返回结果
$0   代表了脚本的名称   如果全路径执行  则脚本名称带全路径
$#   获取脚本传参的总个数 












字符的删除和替换
# 从前往后匹配  ## 贪婪匹配
[root@tomcat backup]# url=www.it.com
[root@tomcat backup]# echo $url
www.it.com
[root@tomcat backup]# echo $url|sed 's#www.##g'
it.com
[root@tomcat backup]# echo ${url#*.}
it.com
[root@tomcat backup]# echo ${url#*.*.}
com

% 从后往前匹配  %% 贪婪匹配
[root@tomcat backup]# echo $url
www.it.com
[root@tomcat backup]# echo ${url%.*}
www.it
[root@tomcat backup]# echo ${url%.*.*}
www
[root@tomcat backup]# echo ${url%%.*.*}
www






[root@tomcat backup]# echo $url
www.it.com
[root@tomcat backup]# echo $url|sed 's#www#aaa#g'
aaa.it.com
[root@tomcat backup]# echo ${url/www/aaa}
aaa.it.com
[root@tomcat backup]# echo ${url//w/a}
aaa.it.com































7.数值运算

7.1 expr 1 + 1   整数运算  

[root@tomcat backup]# expr 1+1
1+1
[root@tomcat backup]# expr 1 + 1
2
[root@tomcat backup]# expr 1 - 10
-9
[root@tomcat backup]# expr 1 * 10
expr: syntax error
[root@tomcat backup]# expr 1 \* 10
10
[root@tomcat backup]# expr 1 / 10
0

#tips:空格必须有


7.2 $()     整数运算-运算效率最高

[root@tomcat backup]# echo $((10+10))
20
[root@tomcat backup]# echo $((10-10))
0
[root@tomcat backup]# echo $((10*10))
100
[root@tomcat backup]# echo $((10/10))
1


[root@tomcat backup]# echo $((10+10+1111111111111111111*33333333333333333333333333333))
3093219949197646375

#tips:空不空格无所谓,这都是整数运算,如果加了小数点,就不可以了,因为小数点不属于整数






7.3  $[]  整数运算

[root@tomcat backup]# echo $[10+10]
20
[root@tomcat backup]# echo $[10-10]
0
[root@tomcat backup]# echo $[10*10]
100
[root@tomcat backup]# echo $[10/10]
1










7.4  bc   整数运算+小数运算

[root@tomcat backup]# echo 10+10.5|bc
20.5
[root@tomcat backup]# echo 10-10.5|bc
-.5
[root@tomcat backup]# echo 10*10.5|bc
105.0
[root@tomcat backup]# echo 10/10.5|bc
0





7.5 awk  python 整数小数运算

[root@tomcat backup]# awk 'BEGIN{print 1-1}'
0
[root@tomcat backup]# awk 'BEGIN{print 1+1}'
2
[root@tomcat backup]# awk 'BEGIN{print 1/1}'
1
[root@tomcat backup]# awk 'BEGIN{print 1*1}'
1
[root@tomcat backup]# awk 'BEGIN{print 1+1.4}'
2.4
[root@tomcat backup]# echo 10 20 |awk '{print $1*$2}'
200
[root@tomcat backup]# echo 10 20 |awk '{print $1+$2}'
30
[root@tomcat backup]# echo 10 20 |awk '{print $1-$2}'
-10
[root@tomcat backup]# echo 10 20 |awk '{print $1/$2}'
0.5



[root@tomcat backup]# python
Python 2.7.5 (default, Nov 14 2023, 16:14:06) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 1+1
2
>>> 1/1
1
>>> 1*1
1
>>> 1-1
0

退出ctrl+d






判断是否输入的为整数

[root@tomcat backup]# cat 2.sh 
#!/bin/bash
read -p "请输入第一个数字:" num
read -p "请输入第二个数字:" num1
echo "$num+$num1=$[$num+$num1]"

[root@tomcat backup]# sh 2.sh 
请输入第一个数字:878
请输入第二个数字:3893
878+3893=4771

[root@tomcat backup]# bash 2.sh 
请输入第一个数字:6727623
请输入第二个数字:dhf
6727623+dhf=6727623



[root@tomcat backup]# cat 2.sh 
#!/bin/bash
read -p "请输入第一个数字:" num
expr 1 + $num >/dev/null 2>&1
[ $? -ne 0 ] && echo "请输入整数" && exit 1
read -p "请输入第二个数字:" num1
expr 1 + $num1 >/dev/null 2>&1
[ $? -ne 0 ] && echo "请输入整数" && exit 2
echo "$num+$num1=$[$num+$num1]"


[root@tomcat backup]# sh 2.sh 
请输入第一个数字:87h
请输入整数
[root@tomcat backup]# echo $?
1
[root@tomcat backup]# sh 2.sh 
请输入第一个数字:33
请输入第二个数字:32d
请输入整数
[root@tomcat backup]# echo $?
2
[root@tomcat backup]# sh 2.sh 
请输入第一个数字:234
请输入第二个数字:234
234+234=468
[root@tomcat backup]# echo $?
0







题目:
做一个计算器   加减乘除 用三种传参的方式完成



[root@tomcat backup]# cat 2.sh 
#!/bin/bash
read -p "请输入二个数字:" num num1
echo "$num+$num1=$[$num+$num1]"

[root@tomcat backup]# bash 2.sh 
请输入二个数字:12 34
12+34=46






结果:
请输入第一个数字:10
请输入第二个数字:20
10+20=30



[root@tomcat backup]# cat 2.sh 
#!/bin/bash
#第一种方法
echo "$1+$2=$[$1+$2]"
echo "$1-$2=$[$1-$2]"
echo "$1*$2=$[$1*$2]"
echo "$1/$2=$[$1/$2]"

#第二种方法
num1=$1
num2=$2
echo "$num1+$num2=$[$num1+$num2]"
echo "$num1-$num2=$[$num1-$num2]"
echo "$num1*$num2=$[$num1*$num2]"
echo "$num1/$num2=$[$num1/$num2]"

read -p "请输入二个数字:" num num1
echo "$num+$num1=$[$num+$num1]"
echo "$num-$num1=$[$num-$num1]"
echo "$num*$num1=$[$num*$num1]"
echo "$num/$num1=$[$num/$num1]"
[root@tomcat backup]# sh 2.sh 23 45
23+45=68
23-45=-22
23*45=1035
23/45=0
23+45=68
23-45=-22
23*45=1035
23/45=0
请输入二个数字:238 35      
238+35=273
238-35=203
238*35=8330
238/35=6





shell脚本第三天

条件表达式

条件表达式


文件测试

test = [ ]
[ -f file ]  常用

test -f file
-e  存在则为真
-f 是否为文件                     常用
-d 是否为目录  是否存在             常用

-x  是否可执行
-r  是否可读
-w 是否可写




[root@tomcat backup]#  [ -e /etc/hosts ]
[root@tomcat backup]# echo $?
0
[root@tomcat backup]#  [ -e /etc/hostsss ]
[root@tomcat backup]# echo $?
1
[root@tomcat backup]# [ -f /etc/hostssss  ] && echo ok || echo error
error
[root@tomcat backup]# [ -f /etc/hosts  ] && echo ok || echo error
ok
[root@tomcat backup]# [ -d /backup/oldboy  ] && echo ok || mkdir /backup/oldboy
[root@tomcat backup]# test -f /etc/passwd
[root@tomcat backup]# echo $?
0
[root@tomcat backup]# test -f /etc/passwd && echo ok || echo error
ok
[root@tomcat backup]# test -d /etc/passwd && echo ok || echo error
error
[root@tomcat backup]# test -x /etc/passwd && echo ok || echo error
error
[root@tomcat backup]# test -r /etc/passwd && echo ok || echo error
ok
[root@tomcat backup]# test -w /etc/passwd && echo ok || echo error
ok


案例:-d
[ -d /backup ] && echo ok || mkdir /backup
案例:-f
[ -d /etc/init.d/functions ] && . /etc/init.d/functions
-------------------
[root@tomcat backup]# . /etc/init.d/functions 
[root@tomcat backup]# [ -d /backup ] && action "nginx start is" /bin/true || action "nginx start is" /bin/false 
nginx start is                                             [  OK  ]
[root@tomcat backup]# 
[root@tomcat backup]# [ -d /backupp ] && action "nginx start is" /bin/true || action "nginx start is" /bin/false 
nginx start is                                             [FAILED]
  

数值比较
语法格式 [ 数值1 比较符 数值2 ]
比较符
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于


[ [ ] ]  建议使用 == != > < >= <= 比较符

 

[root@tomcat backup]# [ 10 -eq 10 ] && echo $? || echo $?
0
[root@tomcat backup]# [ 10 -eq 20 ] && echo $? || echo $?
1
[root@tomcat backup]# [ 10 -lt 20 ] && echo $? || echo $?
0
[root@tomcat backup]# [ 10 -le 20 ] && echo $? || echo $?
0
[root@tomcat backup]# [ 10 -ne 20 ] && echo $? || echo $?
0
[root@tomcat backup]# [ 10 -ne 10 ] && echo $? || echo $?
1
[root@tomcat backup]# [ 10 -ge 10 ] && echo $? || echo $?
0
[root@tomcat backup]# [ 10 -gt 10 ] && echo $? || echo $?
1


[root@tomcat backup]# [ 10 -gt 5 ] && echo "表达式成立" || echo "表达式不成立"
表达式成立
[root@tomcat backup]# [ 10 -gt 10 ] && echo "表达式成立" || echo "表达式不成立"
表达式不成立
[root@tomcat backup]# [ 10 -gt 10 ] && ls ||pwd
/backup
[root@tomcat backup]# [ 10 -gt 9 ] && ls ||pwd
1.sh  2.sh  3.sh  oldboy  passwd



题:
统计磁盘使用率  如果磁盘大于5%则发邮件报警  小于则提示OK

1.如何取出磁盘当前使用率
2.用数值表达式判断大小 如果大发邮件  如果小提示ok
3.测试脚本



#!/bin/bash
disk=`df -h |grep /$|awk '{print $(NF-1)}'`
[ ${disk%\%} -gt 5 ] && echo "磁盘使用已超过5%.当前使用率为$disk"| mail -s "test" 676509301@qq.com || echo ok  




案例二:内存使用率  超过5%则报警 小于则提示ok

[root@tomcat backup]# free |awk 'NR==2{print $3/$2*100}'
21.4591

[root@tomcat backup]# usedisk=`free |awk 'NR==2{print $3/$2*100}'`
[root@tomcat backup]# echo $usedisk
21.5848
[root@tomcat backup]# [ ${usedisk%.*} -gt 5 ] && echo mail ||echo ok
mail
[root@tomcat backup]# [ ${usedisk%.*} -gt 5 ] && echo mail || echo ok
mail

[root@tomcat backup]# [ `free|awk 'NR==2{print $3/$3*100}' |awk -F. '{print $1}'` -gt 4 ] && echo mail || echo error
mail





案例三:统计服务器负载,负载1分钟的值超过2则报警,小于则提示ok

ab -n 20000 -c 20000 http://127.0.0.1/index.html
[ `uptime|awk -F "[ ,.]+" '{print $11}'` -gt 2 ] && echo mail || echo ok

[root@tomcat backup]# ab -n 20000 -c 6000 http://127.0.0.1/index.html

23:02 up  2:28,  2 users,  load average: 0.09, 0.05, 0.05
[root@tomcat backup]# uptime
 14:23:36 up  2:29,  2 users,  load average: 4.10, 0.94, 0.34
[root@tomcat backup]# uptime
 14:23:39 up  2:29,  2 users,  load average: 4.10, 0.94, 0.34
[root@tomcat backup]# uptime
 14:23:40 up  2:29,  2 users,  load average: 3.78, 0.93, 0.34















多整数比较
[root@tomcat backup]# [ 10 -eq 10 -a 10 -lt 100 ]
[root@tomcat backup]# echo $?
0
[root@tomcat backup]# [ 10 -eq 10 -a 10 -lt 100 ] && echo 成立 || echo 不成立
成立
[root@tomcat backup]# [ 10 -eq 10 -a 10 -gt 100 ] && echo 成立 || echo 不成立
不成立
[root@tomcat backup]# [ 10 -eq 10 -0 10 -gt 100 ] && echo 成立 || 
不成立
[root@tomcat backup]# [ 10 -eq 10 -o 10 -gt 100 ] && echo 成立 || echo 不成立
成立
[root@tomcat backup]# [ 10 -eq 10 -o 10 -lt 100 ] && echo 成立 || echo 不成立
成立
[root@tomcat backup]# [ 10 -ne 10 -o 10 -lt 100 ] && echo 成立 || echo 不成立
成立
[root@tomcat backup]# [ 10 -ne 10 -o 10 -gt 100 ] && echo 成立 || echo 不成立
不成立




在中括号里使用 && 和并且 ==and    || 或===or


[root@tomcat backup]# [[ 10 -eq 10 && 100 -gt 50 ]]
[root@tomcat backup]# [[ 10 -eq 10 || 100 -gt 50 ]]
[root@tomcat backup]# [[ 10 -eq 10 -a 100 -gt 50 ]]
-bash: syntax error in conditional expression
-bash: syntax error near `-a'
[root@tomcat backup]# [[ 10 -eq 10 -o 100 -gt 50 ]]
-bash: syntax error in conditional expression
-bash: syntax error near `-o'









字符串比较

字符串比较需加双引号

[root@tomcat ~]# [ "$USER" = "nwq" ] && echo 成立 || echo 不成立
不成立
[root@tomcat ~]# [ "$USER" != "nwq" ] && echo 成立 || echo 不成立
成立


-z   字符串长度为0  则为真
-n   字符串长度不为0 则为真



[root@tomcat ~]# AAA=""
[root@tomcat ~]# echo $AAA

[root@tomcat ~]# [ -z $AAA ]
[root@tomcat ~]# echo $?
0
[root@tomcat ~]# AAA="eeeee"
[root@tomcat ~]# echo $?
0
[root@tomcat ~]# [ -n $AAA ]
[root@tomcat ~]# echo $?
0
[root@tomcat ~]# [ -z $AAA ]
[root@tomcat ~]# echo $?
1


-z 案例    判断是否为空,必须得输入字符  不输入则退出
[root@tomcat backup]# cat 5.sh 
#!/bin/bash
read -p "请输入要更改的主机名:" name
[ -z $name ] && echo "请输入主机名称" && exit


案例   判断是否为整数  
方法一
expr 1 + 变量 
[ $?  -ne 0 ]  && echo "请输入整数" && exit

方法二
[[ $test =~ ^[0-9]+$ ]]








正则比对   需要使用二个[[]]
[root@tomcat backup]# [[ $USER =~ ^r ]]
[root@tomcat backup]# echo $?
0
[root@tomcat backup]# [[ $USER =~ ^l ]]
[root@tomcat backup]# echo $?
1
[root@tomcat backup]# [[ ! $USER =~ ^l ]]
[root@tomcat backup]# echo $?
0






案例
使用三种传参方式  比较二个数值的大小  大了提示大了  小了提示小了
例  要求数字整数做判断  并且不能为空   不允许使用if
sh test.sh 19 20
10<20
sh test.sh 10 10
10=10


[root@tomcat backup]# sh 6.sh 34 98
34<98
34<98
请输入二个数字34 98
34<98
[root@tomcat backup]# cat 6.sh 
#!/bin/bash
#第一种
[ $1 -eq $2 ] && echo "$1=$2"
[ $1 -gt $2 ] && echo "$1>$2"
[ $1 -lt $2 ] && echo "$1<$2"

#第二种
num1=$1
num2=$2
[ $num1 -eq $num2 ] && echo "$num1=$num2"
[ $num1 -gt $num2 ] && echo "$num1>$num2"
[ $num1 -lt $num2 ] && echo "$num1<$num2"

#第三种
read -p "请输入二个数字" num1 num2 
[ $num1 -eq $num2 ] && echo "$num1=$num2"
[ $num1 -gt $num2 ] && echo "$num1>$num2"
[ $num1 -lt $num2 ] && echo "$num1<$num2"











笔试题:
linux添加默认路由 
route add default gw 10.0.0.254 
route del default gw 10.0.0.254


ip route add 0/0 via 10.0.0.254
ip route del 0/0 via 10.0.0.254



网卡添加多个ip地址
ip addr add 10.0.0.100/24 dev eth0
for i in {1..100};do ip addr 10.0.0.$i/24 dev eth0;done


策略路由     vpn拨号
ip ro list   查看策略路由

路由表
[root@centos7mage ~]# cat /etc/iproute2/rt_tables 
#
# reserved values
#
255	local
254	main
253	default
0	unspec
200 test
#
# local
#
#1	inr.ruhep


添加一个表  给这个表设置一个路由 
ip route add 0/0 via 10.0.0.254 table test
ip rule add from 10.0.0.1 table test

10.0.0.1 是你公司的公网ip












#补充:
如何查看环境变量
env
set

变量生效顺序
/etc/profile 开机所有用户加载此文件
. ~/.bashrc
.bash_profile
.bashrc
/etc/bashrc





shell脚本第四天


使用脚本   统计出系统的名称  版本号   内核版本   虚拟平台  eth1ip地址
eth0ip地址  外网ip地址   当前磁盘使用率   当前内存使用率   当前负载
sh test.sh
主机名称:oldboy
系统版本号:7.5
eth0ip地址:10.0.0.7

外网ip地址:curl cip.cc 









for循环

for i in [取值列表]  数字  字符串  命令的结果``  序列  1  2  3   4  5
do
    循环体  要执行什么命令 
done



案例:测试1-255有多少个ip地址在线(能ping通则在线) 10.0.0.1-255
[root@centos7mage ~]# ping -c2 -W1 10.0.1.145 >/dev/null 2>&1
[root@centos7mage ~]# echo $?
0
[root@centos7mage ~]# ping -c2 -W1 10.0.1.14 >/dev/null 2>&1
[root@centos7mage ~]# echo $?
1





案例:批量创建10个用户
1.前缀oldboy1 oldboy2  oldboy3 oldboy4 oldboy...10
输入用户处加判断是否为空
2.创建用户个数  判断是否是整数
3.用户密码统一使用123456

read -p "please input prefix: " pre
判断不能为空
read -p "please input number: " num
判断必须是整数


4.用户添加成功 则输出 create is ok   失败提示 error
for i in `seq 10`;do userdel -r oldboy$i;done































if判断
                                         单分支
if [ 你有钱 ];then
echo "我就嫁给你"
fi


if [ 你有钱 ]                           双分支
then
echo "我就嫁给你"
else [  你有房 ]
echo "不嫁了"
fi





if [ 你有钱 ];then
我就嫁给你
elif [ 你有房 ];then
我也嫁给你
elif [ 你是潜力股 ];then
我考虑考虑
elif [ 你活好yw ];then
我倒贴你 
else [  ];then            可是else结尾 也可以是elif结尾




注释 if ---如果    elif --或者    else--否则(其他都不成立)


总结:
单分支    一个条件  一个结果
双分支    一个条件  二个结果
多分支    多个条件  多个结果



案例:判断输入的二个数字的大小  输出结果

[root@centos7mage ~]# cat diff.sh 
#!/bin/bash
      read -p "请输入二个整数" num1 num2
   if  [ $num1 -gt $num2 ];then
        echo "$num1 > $num2"
   elif [ $num1 -lt $num2 ];then
        echo "$num1 < $num2" 
   else
        echo "$num1 = $num2"
   fi
[root@centos7mage ~]# sh diff.sh 
请输入二个整数10 20
10 < 20
[root@centos7mage ~]# sh diff.sh 
请输入二个整数10 10
10 = 10
[root@centos7mage ~]# sh diff.sh 
请输入二个整数20 10         
20 > 10

   


案例:猜数字  先输出一个随机数 ,read 猜随机数
如果你输入的小了  则提示小了   大了就提示打了  如果成功就提示 猜对了





echo "$RANDOM%100+1"

-bash: 234: command not found
[root@centos7mage ~]# cat ran.sh 
#!/bin/bash
ran=`echo $((RANDOM%100+1))`
while true
do
    let i++
read -p "请输入你要猜的数字: " num
if [ $num -gt $ran ];then
         echo "比随机数大了"
elif [ $num -lt $ran ];then
         echo "比随机数小了"
else
         echo "恭喜你 猜对了 总共猜了 $i 次 "
         exit
fi
done




案例:按照不同的centos版本  安装不同的yum源
1.当前什么版本  如何取出来
cat /etc/centos-release|awk '{print $(NF-1) }'

2.if判断  如果是6  则安装6的yum源  7安装7yum源  5的安装5的yum源


[root@centos7mage ~]# cat osversion.sh 
#!/bin/bash
os=cat /etc/centos-release|awk '{print $(NF-1) }'
if [ ${os%%.*} -eq 7  ];then
         which wget >/dev/null 2>&1
         [ $? -ne 0 ] && yum -y install wget
         mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
         wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
elif [ ${os%%.*}  -eq 6 ];then
         which wget >/dev/null 2>&1
         [ $? -ne 0 ] && yum -y install wget
         mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
         wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-6.10.repo
else
         which wget >/dev/null 2>&1
         [ $? -ne 0 ] && yum -y install wget
         mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
         wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
fi








案例:安装不同的版本php 5.5 7.1 7.2

菜单

[root@centos7mage ~]# sh menu.sh 
########### 1. PHP install 5.3 ########## 
########### 2. PHP install 5.7 ########## 
########### 3. PHP install 7.1 ########## 
########### 4. PHP install 7.2 ########## 
[root@centos7mage ~]# read -p "请输入你要安装的版本号" num
[root@centos7mage ~]# if [ $num -eq 1 ];then yum -y install php5.5 

[root@centos7mage ~]# cat menu.sh 
#!/bin/bash
echo -e "\t\t\t######################################### "
echo -e "\t\t\t########### 1. PHP install 5.3 ########## "
echo -e "\t\t\t########### 2. PHP install 5.7 ########## "
echo -e "\t\t\t########### 3. PHP install 7.1 ########## "
echo -e "\t\t\t########### 4. PHP install 7.2 ########## "
echo -e "\t\t\t######################################### "
cat <<EOF
                       1. INSTALL PHP5.5
                       2. INSTALL PHP5.6
                       3. INSTALL PHP7.1
                       4. INSTALL PHP7.2


EOF

[root@centos7mage ~]# sh menu.sh 
			######################################### 
			########### 1. PHP install 5.3 ########## 
			########### 2. PHP install 5.7 ########## 
			########### 3. PHP install 7.1 ########## 
			########### 4. PHP install 7.2 ########## 
			######################################### 
                       1. INSTALL PHP5.5
                       2. INSTALL PHP5.6
                       3. INSTALL PHP7.1
                       4. INSTALL PHP7.2













16.case

结构
变量=== 名字 自己起的名字   $1 $2   sh case.sh oldboy

case 变量  in              if [ $1 == oldboy ];then 
     模式1)                    echo ok
          命令大礼包  
          ;;
      模式2)
      命令大礼包
      ;;
      模式3)
      命令大礼包
      ;;
      *)
      echo 没有匹配到  
 esac
          




案例:批量删除用户(if判断也可)

1.删除用户的前缀 read -p "please input prefix: " pre
2.删除用户的数量 read -p "用户数量 ": num
[root@centos7mage ~]# cat case.sh 
#!/bin/bash
read -p "Please input username prefix: " pre
read -p "Please input user number: " num

for i in `seq $num`
do
    echo $pre$i
done

read -p "确定要删除以上用户吗?[y|Y|yes|n|N|no] " re

# 更改此处,使循环内的变量引用正确
for i in `seq $num`
do
    user=$pre$i
    id $user >/dev/null 2>&1
    case $re in
           y|Y|yes)
                  if [ $? -eq 0 ];then
                      userdel -r $user
                      if [ $? -eq 0 ]; then
                          echo "$user del is ok"
                      else
                          echo "id: $user: no such user"
                      fi
                  else
                      echo "id: $user: no such user"
                  fi
                  ;;
           n|N|no)
                  echo "不删除,玩啥啊你" 
                  break  # 使用break跳出当前循环而不是exit整个脚本
                  ;;
           *)
                  echo "无效输入,请输入 y|Y|yes 或 n|N|no"
                  ;;
    esac
done










案例:case   要求使用菜单显示
1.help帮助    打印菜单
2.显示内存使用
3.显示磁盘使用
4.显示系统负载
5.显示登录用户
6.查看ip地址
7.查看linux-version


read -p 请输入要查看的系统信息编号:num
1.
2.
3.
4.




[root@centos7mage ~]# cat menu.sh 
#!/bin/bash
menu(){
cat<<EOF
1.help帮助
2.显示内存使用
3.显示磁盘使用
4.显示系统负载
5.显示登录用户
6.查看ip地址
7.查看Linux-version
8.退出
EOF

}
while true
do
read -p "请输入要查看的系统编号:" num
case $num in
         1)
           clear
           menu
           ;;
         2)
           free -h
           ;;
          3)
          df -h
          ;;
          4)
          uptime
          ;;
           5)
           w
          ;;
           6)
           hostname -I
          ;;
           7)
         cat /etc/centos-release |awk '{print $(NF-1)}'
          ;;
           8)
          exit
          ;;

            *)
          echo "请输入要查看的系统编号"
esac
done





案例:nginx启动脚本


命令行方式启动(如果使用命令行启动了, 则无法使用systemctl)

/usr/sbin/nginx      启动命令
/usr/sbin/nginx -s stop    停止命令
/usr/sbin/nginx -s reload   重新加载

重启
/usr/sbin/nginx -s stop
sleep 2  
/usr/sbin/nginx



查看状态
手动过滤监听的端口和pid  打印输出


[root@centos7mage ~]# action "nginx $1 is " /bin/true
nginx  is                                                  [  OK  ]









案例:

[root@centos7mage ~]# cat startnginx.sh 
#!/bin/bash 
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
te=$1
test(){
  if [ $? -eq 0 ];then
      action "Nginx $te is" /bin/true
  else
      action "Nginx $te is" /bin/false
  fi
}
start(){
      /usr/local/nginx/sbin/nginx >/dev/null 2>&1
        }
stop(){
      /usr/local/nginx/sbin/nginx -s stop >/dev/null 2&1
      sleep 2
      /usr/local/nginx/sbin/nginx   
}
restart(){
      stop
      sleep 2
      start
}
reload(){
       /usr/local/nginx/sbin/nginx -s reload >/dev/null 2>&1
}
status(){
      echo  "当前nginx监听端口:`ss -tulpn |grep [n]ginx |awk '{print $5}'`"
      echo " 当前nginxPID为:`ps aux |grep [n]ginx|grep master|awk '{print $2}'`"
}
case $1 in
       start)
               start
               test
           [ $? -eq 0 ] && action "nginx $1 is" /bin/true || action "Nginx $1 is" /bin/false
           ;;
        stop)
                stop
                test
                ;;
         restart)
               restart
                test
            ;;
        reload)
               reload
               test
             ;;
        status)
               status
            ;;
             *)
              echo "USEGE $0[start|stop|reload|restart|status]"
esac








案例:jumpserver
1.需要连接服务器的ip地址
菜单
WEB1=10.0.1.7
WEB2=10.0.1.8
NFS=10.0.1.10
MYSQL
1.web 10.0.1.7
2.web2 10.0.1.8
3.mysql 10.0.1.9
4.NFS 10.0.1.10

2.需要和服务器之间作免秘钥
3.如何登录服务器
ssh root@$WEB
4.使用case语句控制




[root@centos7mage ~]# cat jumpserver.sh 
#!/bin/bash
WEB1=10.0.1.145
WEB2=10.0.1.143
MYSQL=10.0.1.51
NFS=10.0.1.31

menu() {
cat<<EOF
         1) WEB1=10.0.1.145
         2) WEB2=10.0.1.143
         3) MYSQL=10.0.1.51
         4) NFS=10.0.1.31
         5) 菜单
EOF
}

menu
trap "" INT TSTP HUP
while true
do
read -p "请输入需要连接的服务器编号或名称[1|WEB]: " num
case $num in
          1)
          ssh root@$WEB1
          ;;
          2)
          ssh root@$WEB2
          ;;
          3)
          ssh root@$MYSQL
          ;;
          4)
          ssh root@$NFS
          ;;
          5)
          menu
          ;;
          woshiyunwei)
                exit
          ;;
          *)
          read -p "请输入有效的服务器编号或名称[1|WEB]: " num
          ;;
esac
done






17.回顾for
for

for i in 取值列表
do
  执行命令
done
 
 
 
 
 
 while循环
 while [ 条件表达式 ]
do
done
line (变量名)
while read line
do

done<user.txt


使用while循环创建用户名密码
[root@centos7mage ~]# cat while2.sh 
#!/bin/bash
while read line
do
       user=`echo $line|awk '{print $1}'`
       pass=`echo $line|awk '{print $2}'`
       useradd $user   
       echo $pass | passwd --stdin $user
done<user.txt







18.shell内置命令
exit   结束循环
continue   继续执行
break     跳出循环体 执行循环体外的命令



[root@centos7mage ~]# cat ran.sh 
#!/bin/bash
ran=`echo $((RANDOM%100+1))`
echo $ran
for i in {1..100}
do
       [ $i -eq $ran ] && echo -e  "我判断的随机数是 $i"
done




#while true
#do
    #let i++
#read -p "请输入你要猜的数字: " num
#if [ $num -gt $ran ];then
         #echo "比随机数大了"
#elif [ $num -lt $ran ];then
         #echo "比随机数小了"
#else
         #echo "恭喜你 猜对了 总共猜了 $i 次 "
         #exit
#fi
#done



      
移动光标到您想要开始注释的第一行。
按 Shift + V 进入可视行选择模式,然后向下滚动至您想要结束注释的最后一行。
输入 : 进入命令模式,此时底部会出现 :'<,'>,表示当前选中的行范围。
输入 norm I#,这里的 norm 表示执行普通模式下的命令,I 表示在行首插入,# 是注释符号。
按回车键执行命令,所选行的开头都会自动插入 # 注释符。



















shell脚本第五天




shell脚本第六天


19.函数

[root@centos7mage ~]# cat fun.sh 
#!/bin/bash
test(){
     echo "第一种定义方式"
}
function test1 (){
     echo "第二种定义方式"
}
function test2 (){
     echo "第三种定义方式"
}
test
test1
test2




取行方式
  256  wc -l /etc/passwd
  257  cat -n /etc/passwd
  258  grep -n . /etc/passwd
  259  less  -N /etc/passwd
  260  awk '{print $NR,$0}' /etc/passwd
  262  sed '=' /etc/passwd



#!/bin/bash
File="/etc/passwd"

function count () {
    local i=0
    while read line; do
        let i++
    done < "$File"
    echo $i
}

# 调用函数
count


[root@centos7mage ~]# sh funtest.sh 
我在另外脚本调用你的结果计算结果是:20 
[root@centos7mage ~]# cat funtest.sh 
#!/bin/bash
. /root/fun3.sh >/dev/null 2>&1
echo "我在另外脚本调用你的结果`count01`"






20.数组


定义数组
[root@centos7mage ~]# array[0]=linux
[root@centos7mage ~]# echo $array
linux
[root@centos7mage ~]# echo ${array[0]}
linux
[root@centos7mage ~]# array[1]=centos
[root@centos7mage ~]# echo $array
linux
[root@centos7mage ~]# echo ${array[0]}
linux
[root@centos7mage ~]# echo ${array[1]}
centos

[root@centos7mage ~]# declare -a
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='()'
declare -ar BASH_REMATCH='()'
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]="linux" [1]="centos")'

取消数组定义
unset array

[root@centos7mage ~]# array=([0]=linux [1]=shell [2]=mysql [3]=nfs [4]=centos [6]=kvm)
[root@centos7mage ~]# echo ${array[*]}
linux shell mysql nfs centos kvm
[root@centos7mage ~]# echo ${array[1]}
shell
[root@centos7mage ~]# echo ${array[2]}
mysql
[root@centos7mage ~]# echo ${array[3]}
nfs
[root@centos7mage ~]# echo ${array[4]}
centos
[root@centos7mage ~]# echo ${array[5]}

[root@centos7mage ~]# echo ${array[6]}
kvm
[root@centos7mage ~]# echo ${!array[*]}
0 1 2 3 4 6


[root@centos7mage ~]# array=(linux nginx php mysql)
[root@centos7mage ~]# echo ${array}
linux
[root@centos7mage ~]# echo ${!array[*]}
0 1 2 3



[root@centos7mage ~]# cat array.sh 
#!/bin/bash
IP=(
    10.0.1.7
    10.0.1.8
    10.0.1.9
)

for i in "${IP[@]}"
do
    ping -c 1 -W1 $i >/dev/null 2>&1
    [ $? -eq 0 ] && echo "ping $i is ok"
done

-----------------------------


关联数组
字符串作为索引
declare -A array
declare -A 数组名 声明是一个关联数组      (awk中不需要定义关联数组)
declare -A 数组名  声明是一个关联数组
declare -A array='([index1]="shell" [index2]="kvm" [index]="linux" [suiyiqi]="mysql" )'



案例:
[root@centos7mage ~]# sh while.sh 
36
[root@centos7mage ~]# let a++
[root@centos7mage ~]# let a++
[root@centos7mage ~]# let b++
[root@centos7mage ~]# echo $i
2
[root@centos7mage ~]# echo $a
2
[root@centos7mage ~]# echo $b
1
[root@centos7mage ~]# unset array 
[root@centos7mage ~]# declare -A array
[root@centos7mage ~]# let array[m]++
[root@centos7mage ~]# let array[m]++
[root@centos7mage ~]# let array[m]++
[root@centos7mage ~]# let array[m]++
[root@centos7mage ~]# let array[f]++
[root@centos7mage ~]# let array[f]++
[root@centos7mage ~]# let array[f]++
[root@centos7mage ~]# let array[f]++
[root@centos7mage ~]# 
[root@centos7mage ~]# echo ${array[m]}
4





[root@centos7mage ~]# declare -A array
[root@centos7mage ~]# let array[m]++
[root@centos7mage ~]# let array[m]++
[root@centos7mage ~]# let array[m]++
[root@centos7mage ~]# let array[m]++
[root@centos7mage ~]# let array[f]++
[root@centos7mage ~]# let array[f]++
[root@centos7mage ~]# let array[f]++
[root@centos7mage ~]# let array[f]++
[root@centos7mage ~]# 
[root@centos7mage ~]# echo ${array[m]}
4
[root@centos7mage ~]# vim array.sh
[root@centos7mage ~]# vim array1.sh
[root@centos7mage ~]# for i in ${!array[*]};do echo $i${array[$i]};done
f4
m4






[root@centos7mage ~]# vim array1.sh 

#!/bin/bash
declare -A array
while read line
do

     let array[$line]++
done<sex.txt
for i in ${!array[*]}
do
      echo "$i 出现了 ${array[$i]}次"
done


这个 Bash 脚本的主要功能是从一个名为 `sex.txt` 的文本文件中读取每一行内容,并使用关联数组(哈希表)统计每一行内容出现的次数。以下是逐行解释:

1. `#!/bin/bash` —— 这是 Shebang 行,告诉操作系统这个脚本应该使用 `/bin/bash` 解释器来执行。

2. `declare -A array` —— 定义一个关联数组(哈希表)名为 `array`。关联数组允许我们将字符串作为键,并存储任意值(在这里是整数)。

3. `while read line` —— 开始一个循环,逐行读取 `sex.txt` 文件的内容,每一行的内容会被赋值给变量 `line`。

4. `let array[$line]++` —— 对于读取到的每一行,将其作为关联数组 `array` 的键,并将对应键的值加 1。如果键不存在,则先初始化为 0 再加 1。

5. `done<sex.txt` —— 结束 `while` 循环,并指定文件 `sex.txt` 作为循环中 `read` 命令的输入源。

6. `for i in ${!array[*]}` —— 遍历关联数组 `array` 中的所有键。`${!array[*]}` 返回数组的所有键。

7. `echo "$i 出现了 ${array[$i]}次"` —— 输出当前键(即 `sex.txt` 中的一行内容)以及它在文件中出现的次数。

总结一下,整个脚本的作用就是统计 `sex.txt` 文件中每一行内容分别出现了多少次,并将结果逐行输出。例如,如果文件中有两行内容完全一样,则这两行内容在输出时会显示相同的行内容及出现次数 2。











作业:随机数反向破解
通过对应的MD5sum值  找出对应的数字
RANDOM 0-32767
823e163d32619d1eec4b42a02305f549  
f5e493fa9d1451296e7d300ab6224208
9bafc33f02d40d5403914f41e6488e09
2468d0769259d7033b97258f453b0d6c
e37aeed5baebd190c2280d404c351dc8
4a96e38f
71463ecb
b3547439
d00b05c9
85028d79
6e62279
f857fff


作业:统计/etc/passwd bash的种类  出现的次数  最后一列





posted @ 2024-04-06 23:21  三思博客  阅读(34)  评论(0编辑  收藏  举报