[华为云在线课程][Shell脚本编程基础][第二章Shell脚本语言的基本用法][3算术运算及测试][学习笔记]

网友投稿 572 2022-05-29

格式化输出printf

格式

printf "指定的格式" "文本1" "文本2"......

常用格式替换符

%s 字符串 %f 浮点格式 %b 相对应的参数中包含转义字符时,可以使用此替换符进行替换,对应的转义字符会被转义 %c ASCII字符,即显示对应参数的第一个字符 %d,%i 十进制整数 %o 八进制值 %u 不带正负号的十进制值 %x 十六进制(a-f) %X 十六进制(A-F) %% 表示%本身

说明:%#s中的#数字代表此替换符中的输出字符宽度,不足补空格,默认是右对齐,%-10s表示10个字符宽,-表示左对齐

常用转义字符

\a 警告字符,通常为ASCII的BEL字符 \b 后退 \f 换页 \n 换行 \r 回车 \t 水平制表符 \v 垂直制表符 \ 表示\本身

例子:

[root@localhost Code]# printf '%s\n' 1 2 3 4 1 2 3 4 [root@localhost Code]# printf '%f\n' 1 2 3 4 1.000000 2.000000 3.000000 4.000000 [root@localhost Code]# printf '%.2f\n' 1 2 3 4 1.00 2.00 3.00 4.00 [root@localhost Code]# printf '(%s)' 1 2 3 4;echo (1)(2)(3)(4) [root@localhost Code]# printf ' (%s) ' 1 2 3 4;echo (1) (2) (3) (4) [root@localhost Code]# printf ' (%s) \n' 1 2 3 4;echo (1) (2) (3) (4) [root@localhost Code]# printf '%s %s\n' 1 2 3 4 1 2 3 4 [root@localhost Code]# printf '%s %s %s\n' 1 2 3 4 1 2 3 4 #%-10s 表示宽度10个字符,左对齐 [root@localhost Code]# printf "%-10s %-10s %-4s %s \n" 姓名 性别 年龄 体重 小明 男 20 70 小红 女 18 50 姓名 性别 年龄 体重 小明 男 20 70 小红 女 18 50 #将十进制的17转换成16进制数 [root@localhost Code]# printf "%X" 17;echo 11 #将十六进制C转换为十进制 [root@localhost Code]# printf "%d\n" 0xC 12 [root@localhost Code]# VAR="Hello World";printf "3[31m%s3[0m\n" $VAR Hello World [root@localhost Code]# VAR="Hello World";printf "3[31m%s3[0m\n" "$VAR" Hello World

算术运算

shell允许在某些情况下对算术表达式进行求值,比如:let和declare内置命令,(())复合命令和算术拓展。求值以固定宽度的整数进行,不检查溢出,尽管除以0被困并标记为错误。运算符及其优先级,关联性和值与C语言相同。以下运算符列表分组为等优先级运算符级别。级别按降序排列优先。

注意:bash只支持整数,不支持小数

* / % multiplication,division,remainder,%表示取模,即取余数 + - addition,subtraction i++ i-- variable post-increment and post-decrement ++i --i variable pre-increment and post-increment = *= /= %= += -= <<= >>= &= ^= |= assignment - + unary minus and plus ! ~ logical and bitwise negation ** exponentiation << >> left and right bitwise shifts <= >= < > comparison == != equality and inequality & bitwise AND | bitwise OR ^ bitwise exclusive OR && logical AND || logical OR expr?expr:expr conditional operator expr1,expr2 comma

乘法符号有些场景中需要转义

实现算术运算

(1)let var=算术表达式 (2)((var=算术表达式)) 和上面等价 (3)var=$[算术表达式] (4)var=$((算术表达式)) (5)var=$(expr arg1 arg2 arg3 ...) (6)declare -i var=数值 (7)echo '算术表达式' | bc

内建的随机数生成器变量:

$RANDOM 取值范围:0-32767

例子:

#生成 0-49 之间随机数 echo $[$RANDOM%50] #随机字体颜色 [root@localhost Code]# echo -e "3[1;$[RANDOM%7+31]m hello 3[0m" hello

增强型赋值:

+= i+=10 相当于i=i+10 -= i-=j 相当于i=i-j *= /= %= ++ i++ ++i 相当于i=i+1 -- i-- --i 相当于i=i-1

格式:

let varOPERvalue

例子:

[root@localhost Code]# let i=10*2 [root@localhost Code]# echo $i 20 [root@localhost Code]# ((j=i+10)) [root@localhost Code]# echo $j 30

例子:

#自加3后赋值 [root@localhost Code]# let count+=3 [root@localhost Code]# i=10 [root@localhost Code]# let i+=20 [root@localhost Code]# echo $i 30 [root@localhost Code]# j=20 [root@localhost Code]# let i*=j [root@localhost Code]# echo $i 600

例子:

#自增,自减 [root@localhost Code]# unset i j;i=1;let j=i++;echo "i=$i,j=$j" i=2,j=1 [root@localhost Code]# unset i j;i=1;let j=++i;echo "i=$i,j=$j" i=2,j=2

例子:

[root@localhost Code]# expr 2 *3 expr: syntax error [root@localhost Code]# expr 2\* 3 expr: syntax error [root@localhost Code]# expr 2 \* 3 6

例子:

[root@localhost Code]# echo "scale=3;20/3"|bc 6.666

例子:

[root@localhost Code]# i=10 [root@localhost Code]# j=20 [root@localhost Code]# declare -i result=i*j [root@localhost Code]# echo $result 200

例子:计算鸡兔同笼,上有35头,下有94脚,问鸡兔各有多少只?

[root@localhost Code]# cat chook_rabbit.sh #!/bin/bash HEAD= FOOT= RABBIT=$(((FOOT-HEAD-HEAD)/2)) CHOOK=$[HEAD-RABBIT] echo RABBIT:$RABBIT echo CHOOK:$CHOOK [root@localhost Code]# ./chook_rabbit.sh 35 94 RABBIT:12 CHOOK:23

逻辑运算

true,false

1,真 0,假 #注意,以上为二进制

&(与):与0相与,结果为0,和1相与,结果保留原值

1 & 1 = 1 1 & 0 = 0 0 & 1 = 0 0 & 0 = 0

|(或):和1相或结果为1,和0相或,结果保留原值

1 | 1 = 1 1 | 0 = 1 0 | 1 = 1 0 | 0 = 0

!(非)

! 1 = 0 ! true ! 0 = 1 ! false

^(异或)

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

例子:

[root@localhost Code]# true [root@localhost Code]# echo $? 0 [root@localhost Code]# false [root@localhost Code]# echo $? 1 [root@localhost Code]# !true true [root@localhost Code]# ! true [root@localhost Code]# echo $? 1 [root@localhost Code]# ! false [root@localhost Code]# echo $? 0

例子:变量互换

[root@localhost Code]# x=10;y=20;temp=$x;x=$y;y=$temp;echo x=$x,y=$y x=20,y=10 [root@localhost Code]# x=10;y=20;x=$[x^y];y=$[x^y];x=$[x^y];echo x=$x,y=$y x=20,y=10

短路运算

短路与

CMD1 短路与 CMD2 第一个CMD1结果为真 (1),第二个CMD2必须要参与运算,才能得到最终的结果 第一个CMD1结果为假 (0),总的结果必定为0,因此不需要执行CMD2

短路或

CMD1 短路或 CMD2 第一个CMD1结果为真 (1),总的结果必定为1,因此不需要执行CMD2 第一个CMD1结果为假 (0),第二个CMD2必须要参与运算,才能得到最终的结果

条件测试命令

条件测试:判断某需求是否满足,需要由测试机制来实现。专用的测试表达式需要由测试命令辅助完成测试过程,实现评估布尔声明,以使用在条件性环境下进行执行

若真,则状态码变量$?返回0

[华为云在线课程][Shell脚本编程基础][第二章Shell脚本语言的基本用法][3算术运算及测试][学习笔记]

若假,则状态码变量$?返回1

条件测试命令

test EXPRESSION

[EXPRESSION] #和test等价,建议使用[]

[[EXPRESSION]]相关于增强版的[]

注意:EXPRESSION前后必须有空白字符

帮助:

[root@localhost Code]# type [ [ is a shell builtin [root@localhost Code]# help [ [: [ arg... ] Evaluate conditional expression. This is a synonym for the "test" builtin, but the last argument must be a literal `]', to match the opening `['. [[ ... ]]: [[ expression ]] Execute conditional command. [root@localhost Code]# help test test: test [expr] Evaluate conditional expression. Exits with a status of 0 (true) or 1 (false) depending on the evaluation of EXPR. Expressions may be unary or binary. Unary expressions are often used to examine the status of a file. There are string operators and numeric comparison operators as well. The behavior of test depends on the number of arguments. Read the bash manual page for the complete specification.

变量测试

#判断 NAME 变量是否定义 [ -v NAME ] #判断 NAME 变量是否定义并且是名称引用,bash 4.4新特性 [ -R NAME ]

例子:

[root@localhost Code]# unset x [root@localhost Code]# test -v x [root@localhost Code]# echo $? 1 [root@localhost Code]# unset x [root@localhost Code]# echo $? 0 [root@localhost Code]# x=10 [root@localhost Code]# test -v x [root@localhost Code]# echo $? 0 [root@localhost Code]# test -v y | echo $? 0 #注意[ ]需要空格,否则会报下面错误 [root@localhost Code]# [-v y] -bash: [-v: command not found [root@localhost Code]# [ -v y] -bash: [: missing `]' [root@localhost Code]# [ -v y ] [root@localhost Code]# echo $? 0

数值测试

-eq 是否等于 -ne 是否不等于 -gt 是否大于 -ge 是否大于等于 -lt 是否小于 -le 是否小于等于

例子:

[root@localhost Code]# i=10 [root@localhost Code]# j=8 [root@localhost Code]# [ $i -lt $j ] [root@localhost Code]# echo $? 1 [root@localhost Code]# [ $i -gt $j ] [root@localhost Code]# echo $? 0 [root@localhost Code]# [ i -gt j ] -bash: [: i: integer expression expected

算术表达式比较

== != <= >= < >

例子:

[root@localhost Code]# x=10;y=10;((x==y));echo $? 0 [root@localhost Code]# x=10;y=20;((x==y));echo $? 1 [root@localhost Code]# x=10;y=20;((x!=y));echo $? 0 [root@localhost Code]# x=10;y=10;((x!=y));echo $? 1

例子:

[root@localhost Code]# x=10;y=20;((x>y));echo $? 1 [root@localhost Code]# x=10;y=20;((x

字符串测试

test和[]用法

-z STRING 字符串是否为空,没定义或空为真,不空为假 -n STRING 字符串是否不空,不空为真,空为假 STRING 同上 STRING1 = STRING2 是否等于,注意=前后有空格 STRING1 != STRING2 是否不等于 > ASCII码是否大于ASCII码 < ASCII码是否小于ASCII码

[[]]用法

[[ expression ]] 用法 == 左侧字符串是否和右侧的PATTERN相同 注意:此表达式用于[[ ]]中,PATTERN为通配符 =~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配 注意:此表达式用于[[]]中,扩展的正则表达式

建议:当使用正则表达式或通配符使用[[]],其他情况一般使用[]

例子:使用[]

[root@localhost Code]# unset str [root@localhost Code]# [ -z "$str" ] [root@localhost Code]# echo $? 0 [root@localhost Code]# str="" [root@localhost Code]# [ -z "$str" ] [root@localhost Code]# echo $? 0 [root@localhost Code]# str=" " [root@localhost Code]# [ -z "$str" ] [root@localhost Code]# echo $? 1 [root@localhost Code]# [ -z "$str" ] [root@localhost Code]# echo $? 1 [root@localhost Code]# [ "$str" ] [root@localhost Code]# echo $? 0 [root@localhost Code]# str1=hello [root@localhost Code]# str2=world [root@localhost Code]# [ $str1 = $str2 ] [root@localhost Code]# echo $? 1 [root@localhost Code]# str2=hello [root@localhost Code]# [ $str1 = $str2 ] [root@localhost Code]# echo $? 0

例子:在比较字符串时,建议变量放在""中

[root@localhost Code]# NAME="I love Linux" [root@localhost Code]# [ $NAME ] -bash: [: love: binary operator expected [root@localhost Code]# [ "$NAME" ] [root@localhost Code]# echo $? 0 [root@localhost Code]# [ I love Linux ] -bash: [: love: binary operator expected

例子:[[]]和通配符

[root@localhost Code]# FILE="a*" [root@localhost Code]# echo $FILE arg.sh a.sh [root@localhost Code]# [[ $FILE==a* ]] [root@localhost Code]# echo $? 0 [root@localhost Code]# FILE="ab" [root@localhost Code]# [[ $FILE==a* ]] [root@localhost Code]# echo $? 0 #[[]]中如果不想使用通配符*,只想表达*本身,可以用" "引起来,也可以使用转义符 [root@localhost Code]# [[ FILE == a"*" ]] [root@localhost Code]# echo $? 1 [root@localhost Code]# [[ FILE == a\* ]] [root@localhost Code]# echo $? 1 #通配符? [root@localhost Code]# FILE=abc [root@localhost Code]# [[ $FILE == ??? ]] [root@localhost Code]# echo $? 0 [root@localhost Code]# FILE=abcd [root@localhost Code]# [[ $FILE == ??? ]] [root@localhost Code]# echo $? 1 #通配符 [root@localhost Code]# NAME="linux" [root@localhost Code]# [[ "$NAME" == linux* ]] [root@localhost Code]# echo $? 0 [root@localhost Code]# [[ "$NAME" == "linux*" ]] [root@localhost Code]# echo $? 1 [root@localhost Code]# NAME="linux*" [root@localhost Code]# [[ "$NAME" == "linux*" ]] [root@localhost Code]# echo $? 0 #结论:[[ == ]] == 右侧的 * 作为通配符,不要加"",只想作为*,需要加""或者转义

例子:判断合理的考试成绩

[root@localhost Code]# SCORE=101 [root@localhost Code]# [[ $SCORE =~ 100|[0-9]{1,2} ]] [root@localhost Code]# echo $? 0 [root@localhost Code]# [[ $SCORE =~ ^(100|[0-9]{1,2})$ ]] [root@localhost Code]# echo $? 1 [root@localhost Code]# SCORE=10 [root@localhost Code]# [[ $SCORE =~ ^(100|[0-9]{1,2})$ ]] [root@localhost Code]# echo $? 0 [root@localhost Code]# SCORE=abc [root@localhost Code]# [[ $SCORE =~ ^(100|[0-9]{1,2})$ ]] [root@localhost Code]# echo $? 1

文件测试

存在性测试

-a FILE 同 -e -e FILE 文件存在性测试,存在为真,否则为假 -b FILE 是否存在且为块设备文件 -c FILE 是否存在且为字符设备文件 -d FILE 是否存在且为目录文件 -f FILE 是否存在且为普通文件 -h FILE 或 -L FILE 是否存在且为符号链接文件 -p FILE 是否存在且为命名管道文件 -s FILE 是否存在且为套接字文件

例子:

#文件是否存在 [root@localhost Code]# [ -a /home/hello/Code/hello ] [root@localhost Code]# echo $? 1 [root@localhost Code]# [ -a /home/hello/Code/a.sh ] [root@localhost Code]# echo $? 0

文件权限测试:

-r FILE 是否存在且可读 -w FILE 是否存在且可写 -x FILE 是否存在且可执行 -u FILE 是否存在且拥有suid权限 -g FILE 是否存在且拥有sgid权限 -k FILE 是否存在且拥有sticky权限 注意:最终结果由用户对文件的实际权限决定,而非文件属性决定。 例如将写权限关闭,但是root用户还是能执行操作。

文件属性测试

-s FILE 是否存在且非空 -t fd fd 文件描述符是否在某终端中打开 -N FILE 文件自从上一次被读取之后是否被修改过 -O FILE 当前有效用户是否为文件属主 -G FILE 当前有效用户是否为文件属组 FILE1 -ef FILE2 FILE1是否是FILE2的硬连接 FILE1 -nt FILE2 FILE1是否新于FILE2(mtime) FILE1 -ot FILE2 FILE1是否旧于FILE2

关于 () 和 {}

(CMD1;CMD2;…)和{CMD1;CMD2;…;} 都可以将多个命令组合在一起,批量执行

man bash

( list )会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境 帮助查看:man bash 搜索(list) { list; }不会开启子shell,在当前shell中运行,会影响当前shell环境 帮助查看:man bash 搜索{ list; }

组合测试条件

第一种方式 []

[ EXPRESSION1 -a EXPRESSION2 ] 并且,EXPRESSION1和EXPRESSION2都是真,结果才真 [ EXPRESSION1 -o EXPRESSION2 ] 或者,EXPRESSION1和EXPRESSION2只要一个为真,结果就为真 [ ! EXPRESSION ] 取反 说明:-a 和 -o 需要使用测试命令进行,[[]]不支持

第二种方式

COMMAND1 && COMMAND2 并且,短路与,代表条件性的AND THEN 如果COMMAND1成功,将执行COMMAND2,否则,将不执行COMMAND2 COMMAND1 || COMMAND2 或者,短路或,代表条件性的OR THEN 如果COMMAND1成功,将不执行COMMAND2,否则,将执行COMMAND2 !COMMAND 非,取反 注意:如果&&和||混合使用,&&要在前,||要在后

#Linux版俄罗斯轮盘 [ $[RANDOM%6] -eq 0 ] && rm -rf /* || echo "You are lucky"

使用read命令来接受输入

使用read来把输入值分配给一个或多个shell变量,read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量,如果变量名没有指定,默认标准输入的值赋值给系统内置变量REPLY

格式:

read [options] [name,...]

常见选项:

-p 指定要显示的提示 -s 静默输入,一般用于密码 -n N 指定输入的字符长度N -d '字符' 输入结束符

例子:

[root@localhost Code]# read x y z <<< "I love you" [root@localhost Code]# echo $x I [root@localhost Code]# echo $y love [root@localhost Code]# echo $z you

例子:判断用户输入的是否为YES

[root@localhost Code]# cat yesorno.sh #!/bin/bash read -p "Please input yes or no: " input answer=`echo $input|tr 'A-Z' 'a-z'` [ $answer = 'yes' -o $answer = 'y' ] && echo YES [ $answer = 'no' -o $answer = 'n' ] && echo NO [root@localhost Code]# cat yesorno2.sh #!/bin/bash read -p "Please input yes or no: " input [[ $input =~ ^([Yy][Ee][Ss]|[Yy])$ ]] && echo YES [[ $input =~ ^([Nn][Oo]|[Nn])$ ]] && echo NO

Linux Shell

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:《Scrum精髓:敏捷转型指南》—WIP
下一篇:立足岗位,创造价值,华为因你而美好——海思总裁何庭波寄语新员工
相关文章