首页 > 系统相关 >Linux-shell编程(二)

Linux-shell编程(二)

时间:2023-03-01 19:46:50浏览次数:35  
标签:shell Linux 编程 devops echo scripts server root

shell编程(二)

一、运算

1.运算符

运算符 含义
+
-
*
/
% 取余
^或** 幂、指数
i=i+1 i++ 计算次数
j=j+ j+= 求和,累加
&& 并且,前一个命令执行成功,再执行后面的命令(判断)
|| 或者,前一个命令执行失败了,再执行后面的命令(判断)

2.运算方法

运算的命令/符号 说明 应用场景
awk 可以进行计算,带小数,可以与shell脚本进行变量传递 一般计算都可以用awk
bc 带小数 一般计算都可以用bc.需要安装.
expr 进行计算,整数 一般用于检查输入内容是否为数字(方法之一).
let 进行计算,整数,变量直接使用即可 用于计算i++
$(()) 进行计算,整数,变量直接使用即可
$[] 进行计算,整数,变量直接使用即可

2.1 awk

[root@m01 /server/scripts/devops-shell]# awk -vnum1=1 -vnum2=1 'BEGIN{print num1,num2,num1-num2}'
1 1 0
[root@m01 /server/scripts/devops-shell]# num1=2
[root@m01 /server/scripts/devops-shell]# num2=3
[root@m01 /server/scripts/devops-shell]# awk -vnum1=$num1 -vnum2=$num2 'BEGIN{print num1,num2,num1-num2}'
2 3 -1
[root@m01 /server/scripts/devops-shell]# awk -vnum1=$num1 -vnum2=$num2 'BEGIN{print num1,num2,num1**num2}'
2 3 8
[root@m01 /server/scripts/devops-shell]# awk -vnum1=$num1 -vnum2=$num2 'BEGIN{print num1,num2,num1^num2}'
2 3 8

补充:

awk -v 选项用于创建或修改awk的变量。-v是shell脚本与awk的桥梁

在awk各种变量直接使用即可,不要加上$n1,如果加上了会被awk识别为取列

2.2 bc

-l 显示小数
[root@m01 /server/scripts/devops-shell]# echo 5/3 |bc -l
1.66666666666666666666
[root@m01 /server/scripts/devops-shell]# echo 5/3 |bc 
1

2.3 expr

#expr的+号等符号前后要加空格,使用*号要进行转义
[root@m01 /server/scripts/devops-shell]# expr 1 + 1
2
[root@m01 /server/scripts/devops-shell]# expr 1+1
1+1
[root@m01 /server/scripts/devops-shell]# expr 1 + 1
2
[root@m01 /server/scripts/devops-shell]# expr 0 + 0 
0
[root@m01 /server/scripts/devops-shell]# echo $?
1
[root@m01 /server/scripts/devops-shell]# expr 0 + 0 + 1
1
[root@m01 /server/scripts/devops-shell]# echo $?
0
[root@m01 /server/scripts/devops-shell]# num1=1
[root@m01 /server/scripts/devops-shell]# num2=2
[root@m01 /server/scripts/devops-shell]# expr $num1 + $num2
3
[root@m01 /server/scripts/devops-shell]# echo $?

注意事项:

expr计算0+0 查看命令的返回值

expr进行计算的时候,结果为0,$? 返回值就是1

2.4 案例:对输入的内容检查是否为数字

[root@m01 /server/scripts/devops-shell]# cat check_num.sh 
#!/bin/bash
##############################################################
# File Name:check_num.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

read -p "请输入信息:"  num

expr ${num} + 999  &>/dev/null

if [ $? -eq 0 ];then
	echo "您输入${num}的是数字"
else
	echo "您输入${num}的不是数字"

fi

2.5 案例:计算器,传入脚本中2个参数,进行计算, 输出结果。

[root@m01 /server/scripts/devops-shell]# cat calc.sh 
#!/bin/bash
##############################################################
# File Name:calc.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

num1=$1
num2=$2

expr ${num1} + ${num2} + 999 &>/dev/null

if [ $? -ne 0 ];then
	echo "执行$0 脚本,请输入两个数字"
	exit 1
fi

jia=`awk -vn1=$num1 -vn2=$num2 'BEGIN{ print n1+n2 }'`
jian=`awk -vn1=$num1 -vn2=$num2 'BEGIN{ print n1-n2 }'`
cheng=`awk -vn1=$num1 -vn2=$num2 'BEGIN{ print n1*n2 }'`
chu=`awk -vn1=$num1 -vn2=$num2 'BEGIN{ print n1/n2 }'`

cat<<EOF
$num1 + $num2 的结果为 $jia
$num1 - $num2 的结果为 $jian
$num1 * $num2 的结果为 $cheng
$num1 / $num2 的结果为 $chu
EOF

二、判断

1.条件表达式

1.1格式

条件表达式也可以叫条件测试语句

1.2面试题 [] [[]]区别

含义与特点 test或[] [[ ]]与(( ))
共同点 都可以用于判断 都可以用于判断
区别1 仅支持普通判断,不支持正则 普通判断,支持正则
区别2 表示逻辑关系(与或非)符号不同 -a -o ! -gt [[]] && || ! > < <= >=

1.3 判断文件

条件表达式 说明
-f file 判断是否存在,判断这个是否为文件,如果是则为真(成立)
-d dir 判断是否存在,判断这个是否为目录,如果是则为真(成立)
-x executable 判断是否存在,是否有执行权限
-s size 判断是否存在,文件大小是否大于0 (是否为空) 非空为真
-r 是否有读权限
-w 是否有写权限
-nt newer than 两个文件修改时间 是否更加新
-ot older than 两个文件修改时间 是否更加老
-L 软连接
-e 是否存在(任何类型文件)
[root@m01 /server/scripts/devops-shell]# [ -f /etc/hostnam ] && echo 存在 || echo 不存在
不存在
[root@m01 /server/scripts/devops-shell]# [ -f /etc/hostname ] && echo 存在 || echo 不存在
存在
[root@m01 /server/scripts/devops-shell]# [ -d /etc/ ] && echo 存在 || echo 不存在
存在
[root@m01 /server/scripts/devops-shell]# [ -d /etc1/ ] && echo 存在 || echo 不存在
不存在

温馨提示:执行流程

&& 表示前面命令执行成功然后执行echo 成立。

|| 表示前面命令执行失败了,echo 失败

1.4 对比字符串

条件表达式 说明
"str1" = "str2" str1 是否等于str2,如果相等则为真
"str1" != "str2" str1 是否等于str2,如果不相等则为真
-z "str" zero 检查str字符串是否为空,空的则为真
-n "str" not zero 检查str字符串是否为空,非空的则为真
[root@m01 /server/scripts/devops-shell]# test=123
[root@m01 /server/scripts/devops-shell]# [ -n "$test" ] && echo "变量存在且有值" ||echo "变量不存在或没值"
变量存在且有值
[root@m01 /server/scripts/devops-shell]# unset test
[root@m01 /server/scripts/devops-shell]# [ -n "$test" ] && echo "变量存在且有值" ||echo "变量不存在或没值"
变量不存在或没值

1.5 比大小(整数)

不支持小数的对比,仅支持整数

条件表达式 [] [[ ]]
大于 -gt great than >
大于等于 -ge great equal >=
小于 -lt less than <
小于等于 -le less equal <=
等于 -eq equal ==
不等于 -ne not equal !=

1.6 逻辑判断

条件表达式 [] [[ ]]
与(同时成立) 条件1 -a 条件2 (and) &&
或(只有有个成立的就行) 条件1 -o 条件2 (or) ||
非(取反) ! !

1.7 使用正则判断

#案例:使用正则精确匹配数字
[root@m01 /server/scripts/devops-shell]# num=123
[root@m01 /server/scripts/devops-shell]# [[ $num =~ ^[0-9]+$ ]]
[root@m01 /server/scripts/devops-shell]# [[ $num =~ ^[0-9]+$ ]] && echo "是数字" || echo "不是数字"
是数字
[root@m01 /server/scripts/devops-shell]# num=123aaa
[root@m01 /server/scripts/devops-shell]# [[ $num =~ ^[0-9]+$ ]] && echo "是数字" || echo "不是数字"
不是数字
[root@m01 /server/scripts/devops-shell]# num=-1
[root@m01 /server/scripts/devops-shell]# [[ $num =~ ^-?[0-9]+$ ]] && echo "是数字" || echo "不是数字"
是数字

1.8 案例:优化之前的计算器脚本,加入正则判断参 数是否为数字

[root@m01 /server/scripts/devops-shell]# cat calc_regx.sh 
#!/bin/bash
##############################################################
# File Name:calc.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

num1=$1
num2=$2


[[ $num1 =~ ^-?[0-9]+$ ]]||{
	echo $num1 不是数字
	exit 1
}
[[ $num2 =~ ^-?[0-9]+$ ]]||{
        echo $num2 不是数字
	exit 1
}




jia=`awk -vn1=$num1 -vn2=$num2 'BEGIN{ print n1+n2 }'`
jian=`awk -vn1=$num1 -vn2=$num2 'BEGIN{ print n1-n2 }'`
cheng=`awk -vn1=$num1 -vn2=$num2 'BEGIN{ print n1*n2 }'`
chu=`awk -vn1=$num1 -vn2=$num2 'BEGIN{ print n1/n2 }'`

cat<<EOF
$num1 + $num2 的结果为 $jia
$num1 - $num2 的结果为 $jian
$num1 * $num2 的结果为 $cheng
$num1 / $num2 的结果为 $chu
EOF

[root@m01 /server/scripts/devops-shell]# sh calc_regx.sh 10 20
10 + 20 的结果为 30
10 - 20 的结果为 -10
10 * 20 的结果为 200
10 / 20 的结果为 0.5
[root@m01 /server/scripts/devops-shell]# sh calc_regx.sh aa 20
aa 不是数字
[root@m01 /server/scripts/devops-shell]# sh calc_regx.sh 10 aa
aa 不是数字

2. if

2.1 单分支判断

if 条件;then
   满足条件后执行的内容。
fi

if 条件
then
   满足条件后执行的内容。
fi

2.2 双分支判断

if 条件;then
   满足条件后执行的内容。
else
   不满足条件执行的内容。
fi
#案例:检查根分区磁盘空间使用率
#如果大于等于80%提示磁盘空间不足.
#否则提示磁盘空间正常.
[root@m01 /server/scripts/devops-shell]# cat disk_check.sh 
#!/bin/bash
##############################################################
# File Name:disk_check.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

error=80
used=`df -h|awk '$6=="/"{print $5}'|awk -F '%' '{print $1}'`

if [ ${used} -ge ${error} ];then
	echo "磁盘使用率为${used}%,磁盘空间不足"
else
	echo "磁盘使用率为${used}%"
fi

2.3 多分支判断

if 条件;then
   满足条件后执行的内容。
elif 条件;then   #else if
   满足elif条件,执行的内容。
elif 条件;then
   满足elif条件,执行的内容。  
else
   不满足条件执行的内容。
fi

[root@m01 /server/scripts/devops-shell]# cat compare_num.sh 
#!/bin/bash
##############################################################
# File Name:compare_num.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

read -p '请输入两个数字:' num1 num2

[[ $num1 =~ ^-?[0-9]+$ ]]||{
	echo $num1 不是数字
	exit 1
}
[[ $num2 =~ ^-?[0-9]+$ ]]||{
        echo $num2 不是数字
	exit 1
}

if [ $num1 -eq $num2 ];then
	echo "$num1 = $num2"
elif [ $num1 -gt $num2 ];then
	echo "$num1 > $num2"
else 
	echo "$num1 < $num2"
fi 

#案例:输出指定用户的信息
温馨提示:这个脚本未来可以用于做安全检查。
检查
    是否输入了用户名。
    这个用户是否存在,如果不存在则退出,提示用户不存在。
    如果用户存在则输出下面的信息:
        是否可以登录
        用户uid,gid
        用户家目录
        最近1次登录情况。
[root@m01 /server/scripts/devops-shell]# cat secure_check_user.sh 
#!/bin/bash
##############################################################
# File Name:secure_check_user.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

#输入用户名
read -p "请输入用户名:" user

#检查是否输入
if [ $# -eq 1 ];then
	echo "请输入用户名"
fi

id ${user} &> /dev/null

#判断用户是否存在
if [ $? -ne 0 ];then
	echo "${user} 不存在"
	exit 1	
fi

#判断用户是否可以登录
user_shell=`awk -F ':' -vname=${user} '$1==name{print $NF}' /etc/passwd`

if [ ${user_shell} = '/bin/bash' ];then
	user_login="用户可以登录"
else
	user_login="用户不可以登录"
fi

user_uid=`awk -F ':' -vname=${user} '$1==name{print $3}' /etc/passwd`
user_gid=`awk -F ':' -vname=${user} '$1==name{print $4}' /etc/passwd`
user_home=`awk -F ':' -vname=${user} '$1==name{print $(NF-1)}' /etc/passwd`
user_lastlog=`lastlog |grep -w ${user}`

#输出结果
echo "===================================="
echo "用户名:${user}"
echo "用户uid:${user_uid}"
echo "用户gid:${user_gid}"
echo "用户家目录:${user_home}"
echo "用户最后一次登录信息:${user_lastlog}"
echo "===================================="

[root@m01 /server/scripts/devops-shell]# sh secure_check_user.sh
请输入用户名:a
a 不存在
[root@m01 /server/scripts/devops-shell]# sh secure_check_user.sh
请输入用户名:root
====================================
用户名:root
用户uid:0
用户gid:0
用户家目录:/root
用户最后一次登录信息:root             pts/0    10.0.0.1         Fri Feb 24 14:53:20 +0800 2023
====================================


#注意:
awk在脚本中用的话,参数要用-v

3.case

3.1 概述

case语句格式

case "变量"  in
    start)  
     命令1
    
    stop)
     命令2
    
    restart)
     命令3
    
     *)
     错误提示
esac

case语句vs if多分支

case 一般用于固定的菜单选择情况.运行脚本用户输入1,2,3,4. start|stop|restart....

if 可以用于一些范围的比较.

3.2案例 会所菜单展示程序

[root@m01 /server/scripts/devops-shell]# cat case_menu.sh 
#!/bin/bash
##############################################################
# File Name:case_menu.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

cat <<EOF
 本会所可选的套餐
    输入1选择: 138套餐) 吃饱套餐
    输入2选择: 443套餐) 吃饱喝足套餐
    输入3选择: 888套餐) 吃喝拉撒套餐
    输入4选择: 1688套餐) 你想干啥就干啥套餐
EOF

read -p "请您选择套餐:" num

case "$num" in
	1)
	echo "您选择了138套餐) 吃饱套餐"
	;;
	2)
	echo "您选择了443套餐) 吃饱喝足套餐"
	;;
	3)
	echo "您选择了888套餐) 吃喝拉撒套餐"
	;;
	4)
	echo "您选择了1688套餐) 你想干啥就干啥套餐"
	;;
	5)
	echo "恭喜您,激活了会所的惊喜套餐"
	;;
	*)
	echo "本会所没有此套餐,请重新选择"
esac

3.3 案例 判断用户输入的是yes还是no

[root@m01 /server/scripts/devops-shell]# cat case_yes_no.sh 
#!/bin/bash
##############################################################
# File Name:case_yes_no.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

read -p "input yes or no:" choice

case "$choice" in
	yes|y|Y|Yes) echo "您输入的是yes" ;;
	no|n|N|No)   echo "您输入的是no"  ;;
esac
[root@m01 /server/scripts/devops-shell]# sh case_yes_no.sh 
input yes or no:y
您输入的是yes
[root@m01 /server/scripts/devops-shell]# sh case_yes_no.sh 
input yes or no:n
您输入的是no

三、函数

1.概述

应用场景:

在书写脚本的时候,尽量使用函数,规范脚本。

让脚本的开发,更加模块化。

方便后期调试,调试的时候只需要注释函数即可。

2.格式及实战应用

#定义方式01 最完整
function show() {
命令
命令
内容
 return n  #函数的返回值
}

#定义方式02   精简写法 一般使用这一种.
show() {
命令
命令
内容
 return n  #函数的返回值
}

#定义方式03    
function show {
命令
命令
内容
 return n  #函数的返回值
}

3.函数基本格式与使用

[root@m01 /server/scripts/devops-shell]# cat func.sh 
#!/bin/bash
##############################################################
# File Name:func.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

show(){
	echo "世界,你好!!!!"
}
show

[root@m01 /server/scripts/devops-shell]# sh func.sh 
世界,你好!!!!

4.函数传参

位置参数 shell脚本中 函数中
$n 脚本的第n个参数 函数的第n个参数
$0 脚本的名字 脚本的名字
$# 脚本的参数的格式 函数参数个数
$@/$* 脚本所有的参数 函数所有的参数
[root@m01 /server/scripts/devops-shell]# cat func_params.sh 
#!/bin/bash
##############################################################
# File Name:func_params.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

show() {
cat <<EOF
    show函数的参数个数:$#
    show函数的所有参数:$*
    $1.com
    $1.cn
    $1.org
    $1.企业
    $1.icu
    $1.我爱你
EOF
}


show wh wh123
#show $1      #这是脚本的第1个参数
[root@m01 /server/scripts/devops-shell]# sh func_params.sh
    show函数的参数个数:2
    show函数的所有参数:wh wh123
    wh.com
    wh.cn
    wh.org
    wh.企业
    wh.icu
    wh.我爱你

5.案例:sersync服务管理脚本

书写脚本,用于管理sersync服务.
sh data_sync.sh start|stop|restart|status
分析
如果用户输入的是start,则运行sersync启动的命令。
如果用户输入的是stop,则运行关闭sersync的命令。
如果用户输入的是status,则显示sersync是否运行中,pid。
如果用户输入的是restart,则运行stop的命令,然后运行start的命令。
如果用户输入的是其他的内容,则提示输入错误,提示格式。
[root@m01 /server/scripts/devops-shell]# cat sersync.sh 
#!/bin/bash
##############################################################
# File Name:sersync.sh
# Version:V1.0
# Author:wh
# Desc:
##############################################################

choice=$1

sersync_pid=`ps -ef |grep sersync2.*xml|grep -v grep |awk '{print $2}'`
sersync_count=`ps -ef |grep sersync2.*xml |grep -v grep |wc -l`
#开启服务
sersync_start(){
	if [ ${sersync_count} -eq 0 ];then	
		sersync2 -rdo /app/tools/sersync/confxml.xml &>/dev/null
	else
		echo "sersync已启动"
	fi
}

#关闭服务
sersync_stop(){
	if [ ${sersync_count} -eq 0 ];then
		echo "sersync未启动"
	else
		kill ${sersync_pid}
	fi
}

#重启服务
sersync_restart(){
        if [ ${sersync_count} -ne 0 ];then
                kill ${sersync_pid}
        fi
	sersync2 -rdo /app/tools/sersync/confxml.xml &>/dev/null
}

#服务状态
sersync_status(){
	if [ ${sersync_count} -eq 0 ];then
		echo "sersync未启动"
	else
		echo "sersync is running,pid为${sersync_pid}"
	fi	
}

#错误提示
error_msg(){
	echo "help:$0 {start|stop|restart|status}" 
}

case $choice in
	start)   sersync_start ;;
	stop)    sersync_stop ;;
	restart) sersync_restart ;;
	status)  sersync_status ;;
	*)       error_msg ;;
esac

温馨提示:

脚本名字尽量不要包含服务名字.

原因: 脚本运行的时候也是个进程,ps会过滤出这个进程,导致判断失败.

解决:

方案01: 书写脚本,脚本的文件名不包含服务名字即可.

方案02: 过滤进程的时候排除下文件名字(脚本文件)

四、案例 检查指定的地址的端口是否可以访问

[root@m01 /server/scripts/devops-shell]# cat check_access.sh 
#!/bin/bash
##############################################################
# File Name:check_access.sh
# Version:V1.0
# Author:wh
# Desc: 检查指定的地址的端口是否可以访问
##############################################################

ip=$1
port=$2

if [ $# -ne 2 ];then
	echo "请输入ip和端口"
	exit
fi


check_port(){
	state=`nmap -p${port} ${ip} |grep ${port}|awk '{print $2}'`
#	state=`nmap -p${port} ${ip} |grep -wc open|wc -l`
#       state=`echo q |telnet -e q ${port} ${ip}`
	if [ "$state" = "open" ];then
		echo "${ip}的${port}开启"
	else
		echo "${ip}的${port}关闭"
	fi
}

main(){
	check_port
}
main

五、案例 检查指定url是否可以访问

[root@m01 /server/scripts/devops-shell]# cat check_url.sh 
#!/bin/bash
##############################################################
# File Name:check_url.sh
# Version:V1.0
# Author:wh
# Desc:检查url是否可以访问
##############################################################

url=$1

if [ $# -ne 1 ];then
        echo "请输入正确的url"
        exit
fi

check_url(){
	curl ${url} &>/dev/null
#	curl -s -I www.baidu.com |awk 'NR==1{print $2}'
	if [ $? -eq 0 ];then
		echo "${url} 可以访问"
	else
		echo "${url} 不能访问"
	fi
}

check_url


#补充:
wget方法
wget -q  spider   www.baiduavavavavavaavvvvvvv.com
-q不输出额外内容
spider不下载文件,仅仅访问测试.

标签:shell,Linux,编程,devops,echo,scripts,server,root
From: https://www.cnblogs.com/world-of-yuan/p/17169454.html

相关文章

  • 【离线数仓环境搭建】安装linux及安装JDK
    创建新的虚拟机配置网络    安装vimsudoyuminstall-yvim 修改免密sudovim/etc/sudoers(执行安装命令的时候,不再需要输入密码)  查看防火墙状态......
  • Linux-shell编程(三)
    shell编程(三)一、循环1.循环概述循环类型格式说明for循环for变量in清单(列表);do命令;donefor((i=1;i<=10;i++));doecho$i;done最常用的循环w......
  • Linux下的rsync远程增量备份详解
    (Linux下的远程增量备份详解)一、rsync工具介绍1.rsync工具简介rsync是linux系统下的数据镜像备份工具。使用快速增量备份工具RemoteSync可以远程同步,支持本地复制,或者......
  • Linux系统的进程管理
    (Linux系统的进程管理)一、系统进程介绍1.进程概念进程process是指正在执行的程序;是程序正在运行的一个实例。它由程序指令,和从文件、其它程序中读取的数据或系统用户的......
  • Linux通过Tomcat部署war包
    Linux通过Tomcat部署war包​ 前提:Linux上已经安装好tomcat、jdk等环境​ 将war包丢到服务器上​ cd到tomcat安装路径下的webapps/ROOT/下,删除里面的所有文件:......
  • Linux操作命令(七) 1.cut命令 2.paste命令 3.tr命令
    1、cut命令常用参数参数描述-b以字节为单位进行分割-c以字符为单位进行分割-d自定义分隔符,默认为制表符-f自定义字段--complement抽取整个文本......
  • Linux关闭防火墙
    Linux虚拟机关闭防火墙是不安全的,但在仅主机的模式下是没问题的,关闭防火墙是为了让虚拟机集群可以相互访问。命令:serviceiptablesstop验证:serviceiptablesstatus显......
  • 如何确定我的 python shell 是以 32 位还是 64 位执行的?
    如何从shell内部判断shell处于什么模式?我试过查看平台模块,但它似乎只是告诉你“用于可执行文件的位架构和链接格式”。我的二进制文件被编译为64位(我在OSX10......
  • java AES加密、解密(兼容windows和linux)
     1.准备工作2018年10月24日10点46分importjava.security.SecureRandom;importjavax.crypto.Cipher;importjavax.crypto.KeyGenerator;importjavax.crypto.SecretKe......
  • linux UEFI引导重新安装系统grub启动项
    系统无法启动,重新安装系统grubV80-20220613UEFI引导重新安装系统grub启动项挂载系统镜像iso,进入磁盘分区页面时,进行如下操作:ctlr+alt+F2cat/proc/partitionsfdis......