Shell阶段02 shell变量运算(整数运算/小数运算), 条件表达式(文件比较), 调用函数库, 数字的比较, 逻辑运算, 短路运算

Shell变量运算

加减乘除 求余
num1 + num2
num1 - num2
num1 * num2
num1 / num2
num1 % num2        求余

整数运算

expr
$(())  #运算效率最高
$[]
let
只支持整数运算,不支持小数运算

expr    数值之间必须要有空格进行分开,当使用*乘的时候,需要对其进行转义使用,不能进行次方运算

[root@shell01 scripts]# expr 1 + 1
2
[root@shell01 scripts]# num1=10
[root@shell01 scripts]# num2=5
[root@shell01 scripts]# expr $num1 + $num2
15
[root@shell01 scripts]# expr $num1 \* $num2      #这里\取消*的特殊含义
50
[root@shell01 scripts]# expr $num1 / $num2
2
[root@shell01 scripts]# expr $num1 % $num2
0

$(())    没有严格的格式要求,不能进行次方运算

[root@shell01 scripts]# echo $(($num1+$num2))    #$(())没有严格的格式要求,当中不用有空格
15
[root@shell01 scripts]# echo $(( $num1 - $num2 ))
5
[root@shell01 scripts]# echo $(( $num1 * $num2 ))
50
[root@shell01 scripts]# echo $(( $num1 / $num2 ))
2
[root@shell01 scripts]# echo $(( $num1 % $num2 ))
0

$[]        没有严格的格式要求,不能进行次方运算

[root@shell01 scripts]# echo $[$num1+$num2]
15
[root@shell01 scripts]# echo $[$num1 - $num2]
5
[root@shell01 scripts]# echo $[$num1 * $num2]
50
[root@shell01 scripts]# echo $[$num1 / $num2]
2
[root@shell01 scripts]# echo $[$num1 % $num2]
0

#内建的随机数生成器变量
$RANDOM   #取值范围:0-32767
生成 0 - 49 之间随机数
[root@ubuntu2204 ~]# echo $[$RANDOM%50]
6
let 计数 [root@shell01 scripts]
# a=10 [root@shell01 scripts]# let a++ [root@shell01 scripts]# let a++ [root@shell01 scripts]# echo $a 12 [root@shell01 scripts]# let a-- [root@shell01 scripts]# let a-- [root@shell01 scripts]# echo $a 10

  [root@shell01 ~]# let sum=10+10  #或者 let sum=$num1+$num2
  [root@shell01 ~]# echo $sum
  20

 

  例:i++与++i

  [root@ubuntu2204 ~]# i=1;let j=i++;echo $i $j    

  #i=1; j=i; let i=i+1;echo $i $

  2 1

  [root@ubuntu2204 ~]# i=1;let j=++i;echo $i $j

  #i=1;let i=i+1;j=i;echo $i $j

  2 2

小数运算

bc        awk        python

bc默认是没有的,需要下载
[root@shell01 scripts]# yum install -y bc
[root@shell01 scripts]# bc    #交互式运算一般不用,除法值也有问题
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
... 
1+1
2
3/2
1
[root@shell01 scripts]# echo 10 + 20 |bc
30
[root@shell01 scripts]# echo $num1
10
[root@shell01 scripts]# $num3=3
[root@shell01 scripts]# echo $num1 + $num3 |bc 
13
[root@shell01 scripts]# echo $num1 / $num3|bc  #计算值有问题,没有小数位
3
[root@shell01 scripts]# echo "scale=2;$num1 / $num3"|bc  #scale设定小数位为2位
3.33
[root@shell01 scripts]# echo $num1 ^ $num3 |bc     #次方运算
1000

awk    默认对文件进行操作,加入行处理前BEGIN就不会报错,直接进行计算
BEGIN    行处理前

[root@shell01 scripts]# awk 'BEGIN{print 10 + 5}'
15
[root@shell01 scripts]# awk 'BEGIN{print 10 - 5}'
5
[root@shell01 scripts]# awk 'BEGIN{print 10 * 5}'
50
[root@shell01 scripts]# awk 'BEGIN{print 10 / 5}'
2
[root@shell01 scripts]# awk 'BEGIN{print 10 % 5}'
0
[root@shell01 scripts]# awk 'BEGIN{print 10 ^ 5}'    #支持次方运算
100000
[root@shell01 scripts]# awk 'BEGIN{print 10 / 3}'    #除法小数位是随机的,最大5位
3.33333
[root@shell01 scripts]# awk 'BEGIN{printf "%.3f\n",10/3}' #自定义小数位,采用python写法,\n进行换行
3.333

#注意awk用外部变量,要用双引号
[root@shell01 scripts]# awk "BEGIN{print $num1/$num2}"
2

#awk可以用内部变量  -v #自定义内部变量
[root@shell01 scripts]# awk -vnum1=10 -vnum2=5 'BEGIN{print num1/num2}' #这里变量前不要加$,不然变列行
2

python

[root@shell01 scripts]# python    #交互式
Python 2.7.5 (default, Oct 30 2018, 23:45:53) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 10/3
3
>>> 10.0/3    #要得到小数,首先把数字变为浮点型
3.3333333333333335

[root@shell01 scripts]# echo "print $num1 + $num2" | python        #这里采用python的写法
15
[root@shell01 scripts]# echo "print $num1 - $num3" | python
7
[root@shell01 scripts]# echo "print $num1 / $num3" | python
3
[root@shell01 scripts]# echo "print ${num1}.0 / $num3" | python
3.33333333333

变量运算案例

1.ps aux命令下,求VSZ列的和        (VSZ虚拟内存集,RSS物理内存集)
#第一种
[root@shell01 ~]# ps aux | awk 'NR>1{print $5}'|xargs    #xargs分组作用,把一列分成一行
125884 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 37116 45744 0 0 0 0 0 0 0 0 0 0 0 0 62052 0 0 228320 26380 58236 73656 201724 612240 99576 300828 473820 225828 126388 110192 573932 112764 220792 89556 89728 161372 116332 89660 0 0 0 0 155464 113640 116332
[root@shell01 ~]# ps aux | awk 'NR>1{print $5}'|xargs |tr ' ' '+'
125884+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+37116+45744+0+0+0+0+0+0+0+0+0+0+0+0+62052+0+0+228320+26380+58236+73656+201724+612240+99576+300828+473820+225828+126388+110192+573932+112764+220792+89556+89728+161372+116332+89660+0+0+0+155464+113640+108352+108076
[root@shell01 ~]# ps aux | awk 'NR>1{print $5}'|xargs |tr ' ' '+'|bc
4863984

#第二种
[root@shell01 ~]# ps aux | awk 'NR>1{i+=$5}END{print i}'    #第五列相加,END等前面计算结束
4531224

#第三种
[root@shell01 scripts]# vim for_vsz.sh
#!/bin/bash
he=0
for i in $(ps aux| awk 'NR>1{print $5}')
do
    he=$(expr $he + $i)
done
echo $he
[root@shell01 scripts]# sh -x for_vsz.sh    #-x显示脚本执行过程


2.写个脚本,实现一个简单的计算器,实现加减乘除
[root@shell01 scripts]# vim jsq.sh
#!/bin/bash
read -p "请输入你要计算的第一个数字:" num1
read -p "请输入你要计算的第二个数字:" num2
echo "$num1 + $num2 = $[ $num1 + $num2 ]"
echo "$num1 - $num2 = $[ $num1 - $num2 ]"
echo "$num1 * $num2 = $[ $num1 * $num2 ]"
echo "$num1 / $num2 = $(awk "BEGIN{print $num1 / $num2}")"

Shell变量案例

1.使用Shell脚本打印,系统版本、内核版本平台、虚拟平台、静态主机名、eth0网卡IP地址、lo网卡IP地址、当前主机的外网IP地址
curl icanhazip.com 或者 curl ifconfig.me #当前主机的外网IP地址 awk
'{print$1,$4}' /etc/redhat-release #系统版本信息 hostnamectl | awk '/Kernel/{print $3}' #Kernel内核版本信息 hostnamectl | awk '/Virtua/{print $2}' #虚拟平台 hostnamectl | awk '/hostname/{print $3}' #静态主机名 ifconfig eth0|awk 'NR==2{print $2}' #eth0网卡IP地址 ifconfig lo|awk 'NR==2{print $2}' #lo网卡IP地址 [root@shell01 scripts]# vim var.sh #!/bin/bash Version=$(awk '{print$1,$4}' /etc/redhat-release) Kernel=$(hostnamectl | awk '/Kernel/{print $3}') Vm=$(hostnamectl | awk '/Virtua/{print $2}') Static_Hostname=$(hostnamectl | awk '/hostname/{print $3}') Eth0=$(ifconfig eth0|awk 'NR==2{print $2}') Lo=$(ifconfig lo|awk 'NR==2{print $2}') Wan=$(curl -s ifconfig.me) #-s:不输出错误和进度信息 echo "当前系统版本号为: $Version" echo "当前系统内核版本号为: ${Kernel%.e*}" echo "当前系统虚拟化平台为: $Vm" echo "当前系统静态主机名为: $Static_Hostname" echo "当前系统的Eth0网卡IP地址为: $Eth0" echo "当前系统的Lo网卡IP地址为: $Lo" echo "当前系统的外网IP地址为: $Wan" ---------------------------------------------------- 2.需求描述:变量string="Bigdata process is Hadoop, Hadoop is open source project",执行脚本后,打印输出string变量,并给出用户以下选项: #需求 1)打印string长度 2)删除字符串中的所有Hadoop 3)替换第一个Hadoop为Linux 4)替换全部Hadoop为Linux 用户请输入数字1|2|3|4,可以执行对应项的功能。 [root@shell01 scripts]# vim var-1.sh #!/bin/bash #1.定义变量 String='Bigdata process is Hadoop, Hadoop is open source project' #2.打印变量 echo $String #3.输出菜单 cat<<EOF 1)打印string长度 2)删除字符串中的所有Hadoop 3)替换第一个Hadoop为Linux 4)替换全部Hadoop为Linux EOF #4.提示用户输入对应的数字,执行对应的功能 read -p "请输入上方菜单对应的数字,执行对应的功能[1|2|3|4]: " Num #5.根据用户输入的数字进行执行对应的功能 if [ $Num -eq 1 ];then echo "打印string长度" echo ${#String} fi if [ $Num -eq 2 ];then echo "删除字符串中的所有Hadoop" echo ${#String//Hadoop/} fi if [ $Num -eq 3 ];then echo "替换变量中第一个Hadoop为Linux" echo ${#String/Hadoop/Linux} fi if [ $Num -eq 4 ];then echo "替换变量中全部Hadoop为Linux" echo ${#String//Hadoop/Linux} fi

 

条件表达式

文件比较

[]======test    #中括号相当于test命令, []比较常用
[ -f file ] 文件是否存在 且为普通文件    重点    # [后 和 ]前 必须有空格
[ -e file ] 文件/目录存在则为真 [ -e file/dir]
[ -s file ] 如果文件存在且至少有一个字符则为真(判断一个文件是否是空文件) [
-d file ] 目录存在则为真(判断为文件时则为假) 重点 [ -x file ] 文件有执行权限则为真 [ -w file ] 文件可写则为真 [ -r file ] 文件可读则为真 #示例 [root@shell01 ~]# [ -f /etc/hosts ] [root@shell01 ~]# echo $? 0 [root@shell01 ~]# [ ! -d /etc/hosts ] #!取反 [root@shell01 ~]# echo $? 0 [root@shell01 scripts]# test -f /etc/hosts && echo ok || echo error -f 判断文件是否存在
#测试URL地址是否能够访问(调用函数库) [root@shell01 scripts]
# vim ping.sh #!/bin/bash [ -f /etc/init.d/functions ] && . /etc/init.d/functions #加载函数库,service启动用的也是该函数库 read -p "请输入一个网址: " url ping -c 1 -W 1 $url >/dev/null 2>&1  #-c次数 -W超时时间(s) [ $? -eq 0 ] && action "ping $url is" /bin/true || action "ping $url is" /bin/false #函数库使用action -d 判断是否为目录 目录是否存在 [root@shell01 scripts]# [ -d /alex ] || mkdir /alex

数字的比较

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

[root@shell01 scripts]# [ 10 -eq 10 ] && echo ok || echo error
ok

#案例:
统计当前磁盘的使用率 如果大于5% 则把内容写入到以日期为名称的文本中 2019-08-01.txt
如果小了 则把当前的使用率 写入 2019-08-01.txt
1.如何取出当前的使用率
2.条件表达式 整数的比较
3.输出结果到文本
[root@shell01 ~]# [ `df -h|grep /$|awk -F "[ %]+" '{print $(NF-1)}'` -gt 5 ] && echo error || echo ok
error

#案例:
统计系统内存的使用率 如果大于10则 echo 使用率到 以时间命名的文件中
[root@shell01 ~]# free=`free|awk 'NR==2{print $3/$2*100}'`
[root@shell01 ~]# [ ${free%.*} -gt 10 ] && echo error || echo ok

 

#注意也可以用 [[]]
#如果用 [[]], 里面的比较符为    =   !=  >=  <  <=

 

逻辑运算

与:& 和0相与结果为0,和1相与结果保留原值, 一假则假,全真才真

[root@ubuntu2204 ~]# x=$[2&6]
[root@ubuntu2204 ~]# echo $x
2
[root@ubuntu2204 ~]# x=$[7&3]
[root@ubuntu2204 ~]# echo $x
3

或:| 和1相或结果为1,和0相或结果保留原值,一真则真,全假才假

root@ubuntu2204 ~]# x=$[7|3]
[root@ubuntu2204 ~]# echo $x
7

非:!

[root@ubuntu2204 ~]# ! true
[root@ubuntu2204 ~]# echo $?
1

异或:^

异或的两个值,相同为假,不同为真。两个数字X,Y异或得到结果Z,Z再和任意两者之一X异或,将得 出另一个值Y

#变量互换(不通过中间值实现变量值互换)
[root@ubuntu2204 ~]# x=10;y=20;temp=$x;x=$y;y=$temp;echo x=$x,y=$y
x=20,y=10
[root@ubuntu2204 ~]# x=10;y=20;x=$[x^y];y=$[x^y];x=$[x^y];echo x=$x,y=$y
x=20,y=10

 

短路运算

 

短路与 &&

 当 cmd1 的结果为 false 时,整个表达式就是 false, cmd2 不参与运算,这就是所谓的短路

短路或 ||

 当 cmd1 的结果为 true 时,整个表达式就是 true, cmd2 不参与运算,这就是所谓的短路

短路与和或组合

cmd1 || cmd2 && cmd3 这种语法是错误的,不使用;

[root@ubuntu ~]# id tom &>/dev/null && echo "yes" || echo "no"
yes
[root@ubuntu ~]# id tom123 &>/dev/null && echo "yes" || echo "no"
no

#错误写法
[root@ubuntu ~]# id tom &>/dev/null || echo "yes" && echo "no"
no
[root@ubuntu ~]# id tom123 &>/dev/null || echo "yes" && echo "no"
yes
no

 

关于 () 和 {}

( cmd1;cmd2;... ) 和 { cmd1;cmd2;...; } 都可以将多个命令组合在一起,批量执行
( list ) 会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境
{ list; } 不会开启子shell, 在当前shell中运行,会影响当前shell环境,左侧要有空格,右侧要有; 
结束
[root@ubuntu2204 ~]# name=mage;(echo $name;name=wang;echo $name );echo $name
mage
wang
mage

[root@ubuntu2204 ~]# name=mage;{ echo $name;name=wang;echo $name; } ;echo $name
mage
wang
wang
#()会开启子shell
[root@ubuntu2204 ~]# echo $BASHPID
1920
[root@ubuntu2204 ~]# ( echo $BASHPID;sleep 100)
1979
[root@ubuntu2204 ~]# pstree -p
├─sshd(719)───sshd(1906)───sshd(1919)─┬─bash(1920)───bash(1979)───sleep(1980)

#{ } 不会开启子shell
[root@ubuntu2204 ~]# echo $BASHPID
1920
[root@ubuntu2204 ~]# { echo $BASHPID; }
1920

 

posted @ 2024-05-06 18:39  战斗小人  阅读(288)  评论(0编辑  收藏  举报