一篇文章让你搞懂shell变量的运算和条件测试

一、shell变量的运算

先复习一下原码,反码和补码
原码、反码、补码的运算
1、正数的原码 = 反码 = 补码;
2、负数的反码等于它的原码符号位不变,其它位按位取反;
负数的补码等于它的反码加1;
负数的补码的补码即为它的原码 或 补码减1为反码,再符号位不变其他位按位取反即得原码。

要求及目的:
1.shell的运算符有哪些
2.数学计算的命令有哪些,并举例使用
3.${}中的使用,并举例包含(#, ##,%,%%,:, /, //),并举例使用
示例4:删除字符串

运算符

运算符说明
+、-求和、差
*、/、%求乘积,商,余数
**幂运算,例如3**3是求3的立方,即27
+=、-=、*=、/=、%=例a+=1相当于a=a+1
++variable、–variable先将变量variable的值加1,然后再赋给variable; 先将变量variable的值减1,然后再赋给variable
variable++、variable–先使用variable的值,然后再将该变量的值加1; 先使用variable的值,然后再将该变量的值减1
位运算符<<、>>位运算通常出现在整数间,它针对的不是整个整数,而是其二进制表示形式中的某个或者某些位(bit)。例如,2>>1是将二进制形式的2,即10,左移1位,从而变成100,即4。 左移,4<<2,将4左移2位,结果为16; 右移,8>>2,将8右移两位,结果为2
&、|、~、^按位与,8&4,将8和4进行按位与运算,结果为0; 按位或,8|4,将8和4进行按位或运算,结果为12; 按位非,~8,将8进行按位非运算,结果为-9(一个字符占一个字节,即8个二进制位,最高位为1时为负数); 按位异或(a异或b, a、b值不同结果为1,相同结果为0),10^6,将10和6进行按二进制位异或运算,结果为12。
<<=、>>=将变量的值左移指定位数之后重新赋给该变量,x<<=3,将x的值左移3位,重新赋给变量x; 将变量的值右移指定位数之后重新赋给该变量,x>>=4,将变量x的值右移4位后重新赋给变量x。
&=、|=、^=将变量的值与指定的数值按位与之后重新赋给该变量,x&=8,将变量x的值与8按位与运算之后重新赋给变量x; 将变量的值与指定的数值按位或之后重新赋给该变量,x|=7,将变量x的值与7执行按位或运算之后重新赋给变量x; 将变量的值与指定的数值按位异或之后重新赋给该变量,x^=9,将变量x的值与9执行按位异或运算之后重新赋给变量x。

示例1 :

+=,-=,*=,/=,%=

[root@localhost day2]# a=1
[root@localhost day2]# echo $((a+=3))  #相当于a=a+3=1+3=4
4
[root@localhost day2]# echo $((a-=3))   #相当于a=a-3=4-3=1
1

++variable、–variable与variable++、variable–的区别

[root@localhost day2]# a=1
[root@localhost day2]# ((b=++a));echo $a $b    #a=1,先执行a+1的操作,在进行赋值
2 2
[root@localhost day2]# a=1
[root@localhost day2]# ((c=a++));echo $a $c    #a=1,先执行赋值的操作,在进行a+1的操作
2 1

运算操作符与运算命令

运算操作符与运算命令意义说明
(())用于整数运算的常用运算符在(())中使用变量时可以去掉变量前的$符号
let用于整数运算使用let命令可以执行一个或者多个算术表达式,其中的变量名毋需使用$符号
expr可用于整数运算,但还有很多其他的额外功能使用expr时,运算符及用于计算的数字左右都至少有一个空格,否则会报错;使用乘号时,必须使用反斜线屏蔽其特定含义;使用expr做计算,将一个未知的变量和一个已知的整数相加,看返回码是否为0,如果为0就认为做加法的变量为整数,否则就不是整数。
bclinux下的一个计算器程序(适合整数及小数运算)[root@node13 test9]# echo seq -s "+" 10 = seq -s "+" 10 | bc。seq是生成数字序列,-s是指定数字序列之间的分隔符
$[]用于整数运算
awkawk既可以用于整数运
算,也可以用于小数运算
declare定义变量值和属性,-i参数可以用于定义整形变量,做运算

示例2:
实验:计算用户输入的任意两个整数的和、差、乘积、商、余数(采用多种运算操作符)。

[root@localhost day2]# vim number1.sh 
#!/bin/bash
echo "num1=$1"
echo "num2=$2"

echo  "num1+num2=$(($1+$2))"

echo -n "num1*num2="
let let_1=$1*$2
echo $let_1

echo -n "num1/num2="
expr $1 '/' $2

echo -n "num1**num2="
echo "$1 $2" | awk '{print ($1**$2)}'

echo -n "num1%num2="
echo $1%$2 | bc
[root@localhost day2]# bash number1.sh 3 5
num1=3
num2=5
num1+num2=8
num1*num2=15
num1/num2=0
num1**num2=243
num1%num2=3

表达式

表达式说明
${parameter}返回变量的内容
${#parameter}返回变量内容的长度(按字符)
${paramater:offset}在变量${parameter}中,从位置offset之后开始提取子串到结尾
${paramater:offset:length}在变量${parameter}中,从位置offset之后开始提取长度为length的子串
${parameter#word}从变量${parameter}开头开始删除最短匹配的word子串
${parameter##word}从变量${parameter}开头开始删除最长匹配的word子串
${parameter%word}从变量${parameter}结尾开始删除最短匹配的word子串
${parameter%%word}从变量${parameter}结尾开始删除最长匹配的word子串
${parameter/pattern/string}使用string代替第一个匹配的pattern
${parameter//pattern/string}使用string代替所有匹配的pattern
示例3:截取字符串
[root@localhost day2]# str_num="123 456 789"
[root@localhost day2]# echo ${#str_num}	#返回变量长度
11
[root@localhost day2]# echo ${str_num:1}	#指定起始位置为1,一直到结束
23 456 789
[root@localhost day2]# echo ${str_num::5}	#指定长度为5,不指定起始位置默认从开头开始
123 4
[root@localhost day2]# echo ${str_num:2:5}	#指定起始位置和长度
3 456
[root@localhost day2]# echo ${str_num:0-5}	#输出右边的0-5个字符
6 789
[root@localhost day2]# echo ${str_num:0-5:4}  #右边的0-5个字符,字符的个数2
6 78
[root@localhost day2]# echo ${str_num:-5} 	#提取完整字符串
123 456 789
[root@localhost day2]# echo ${str_num: -5} #输出右边的0-5个字符
6 789

示例4:删除字符串

#获取后缀名tar.gz
[root@localhost day2]# filename=testfile.tar.gz
[root@localhost day2]# file=${filename#*.} 
[root@localhost day2]# echo $file tar.gz 
#获取后缀名.gz 
[root@localhost day2]# filename=testfile.tar.gz 
[root@localhost day2]# file=${filename##*.} 
[root@localhost day2]# echo $file 
gz

#截取testfile.tar 
[root@localhost day2]# filename=testfile.tar.gz 
[root@localhost day2]# file=${filename%.*}
[root@localhost ~]# echo $file
testfile.tar
  
#截取testfile 
[root@localhost day2]# filename=testfile.tar.gz 
[root@localhost ~]# file=${filename%%.*} 
[root@localhost ~]# echo $file
testfile

二、shell条件测试

目的及要求:

  1. 条件测试的语法 (()), [[]],[],test,功能以及语法格式
  2. 通过read读入两个整数,并比较他们的大小
  3. 假设执行一个可以携带参数的script,执行该脚本后屏幕会显示如下的数据

条件测试语法

在shell程序中,用户可以使用测试语句来测试指定的条件表达式的条件的真或假。当指定的条件为
真时,整个条件测试的返回值为0;反之,如果指定的条件为假,则条件测试语句的返回值为非0值。

条件测试语法说明
语法1: test <测试表达式>test命令和<测试表达式>之间至少有一个空格
语法2:[ <测试表达式> ]该方法和test命令的用法一样,[]的边界和内容之间至少有一个空格
语法3:[[ <测试表达式> ]]比test和[]更新的语法格式。[[]]的边界和内容之间至少有一个空格。[[]]中可以使用通配符等进行模式匹配
语法4:((<测试表达式>))一般用于if语句里,双小括号两端不需要有空格,测试对象只能是整数

条件测试表达式

常用的有:

常用的文件测试操作符说明
-a/-e文件 文件是否存在
-b 文件文件是否存在,且为块文件,如果文件存在且是一个块文件,则结果为0
-c 文件文件是否存在且为字符文件,如果文件存在且是一个字符文件,则结果为0
-L 文件文件存在且为链接文件则为真
-d 文件文件存在且为目录则为真,即测试表达式成立
-f 文件文件存在且为普通文件则为真,即测试表达式成立
-s 文件文件存在且文件大小不为0则为真
-u 文件文件是否设置suid位,如果设置了suid,则结果为0
-r 文件文件存在且可读为真
-w 文件文件存在且可写为真
-x 文件文件存在且可执行则为真
f1 -nt f2,nt为newer than文件f1比文件f2新则为真,根据文件的修改时间来计算
f1 -ot f2,ot为older than文件f1比文件f2旧则为真,根据文件的修改时间来计算
[root@localhost day2]# man test 	#查看更多的文件测试操作符

字符串测试操作符

常用字符串测试操作说明
-n “字符串”若字符串的长度不为0,则为真,即测试表达式成立,n可以理解为nozero
-z “字符串”若字符串的长度为0,则为真,z可以理解为zero
“串1”=“串2”若字符串1等于字符串2,则为真,可使用==代替=
“串1”!=“串2”若字符串1不等于符串2,则为真

整数测试表达式

在[]以及test中使用的比较符号在(())和[[]]中使用的比较符号说明
-eq==或=相等,全拼为equal
-ne!=不相等,全拼为not equal
-gt>大于,全拼为greater than
-ge>=大于等于,全拼为greaterequal
-lt<小于,全拼为less than
-le<=小于等于,全拼为less equal

逻辑操作符

在[]中使用的逻辑操作符在test、[[]]和(())中使用的逻辑操作符说明
-a&&and,与,两端都为真,则结果为真
-o||or,或,两端有一个为真,则结果为真
not,非,两端相反,则结果为真

例:
实验:通过read读入两个整数,并比较他们的大小

[root@localhost day2]# vim test1.sh
#!/bin/bash
# 使用read,注释为“please input two integers”,输入两个需要比较大小的整数
read -p "please input two integers:" num1 num2
# 检查是不是有两个数,当num1或者num2中出现一个zero,则返回"please input 'two' integers",退出码为1
[ -z "$num1" -o -z "$num2" ] && {
echo "please input 'two' integers"; exit 1; }
# 检查数字是不是为整数,不是整数则返回"please input two 'integers'",退出码为2
expr $num1 + 10 &>/dev/null
return_num1=$?
expr $num2 + 10 &>/dev/null
return_num2=$?
[ "$return_num1" -eq 0 -a "$return_num2" -eq 0 ] || {
echo  "please input two 'integers'"; exit 2; }
#开始比较两个整数的大小,退出码为0
[ "$num1" -lt "$num2" ] && {
echo "$num1 < $num2"; exit 0; }

[ "$num1" -eq "$num2" ] && {
echo "$num1 = $num2"; exit 0; }

[ "$num1" -gt "$num2" ] && {
echo "$num1 > $num2"; exit 0; }
[root@localhost day2]# bash test1.sh 
please input two integers: 2  
please input 'two' integers
[root@localhost day2]# echo $?
1
[root@localhost day2]# bash test1.sh 
please input two integers:-1.1 3
please input two 'integers'
[root@localhost day2]# echo $?
2
[root@localhost day2]# bash test1.sh 
please input two integers:-4 2
-4 < 2
[root@localhost day2]# echo $?
0
[root@localhost day2]# bash test1.sh 
please input two integers:0 0
0 = 0
[root@localhost day2]# echo $?
0

例:
实验:假设执行一个可以携带参数的script,执行该脚本后屏幕会显示如下的数据
程序的文件名;共有几个参数;若参数的个数小于2个则告知用户参数数量太少;全部的参数内容;第一个参数;第二个参数。

[root@localhost day2]# vim test2.sh
#!/bin/bash
#输出程序的文件名
echo "the script name is $0" 
#输出共有几个参数
echo "the parameter number is $#" 
#若参数的个数小于2个则告知用户参数数量太少;全部的参数内容;
[ "$#" -lt 2 ] && echo "the number of parameter is less than 2." && exit 0
#显示所有参数
echo "whole parameter is '$@'"
#第一个参数
echo "the first parameter is $1"
#第二个参数
echo "the second parameter is $2"
[root@localhost day2]# bash test2.sh 1 
the script name is test2.sh
the parameter number is 1
the number of parameter is less than 2.
[root@localhost day2]# bash test2.sh 1 2 3 4 5 
the script name is test2.sh
the parameter number is 5
whole parameter is '1 2 3 4 5'
the first parameter is 1
the second parameter is 2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值