龙空技术网

Linux-Shell脚本编程(二)

不寐旋律 157

前言:

目前我们对“nginx shell”大致比较注重,咱们都想要知道一些“nginx shell”的相关知识。那么小编在网络上汇集了一些有关“nginx shell””的相关知识,希望咱们能喜欢,大家一起来了解一下吧!

续接上回。。。

2.8 格式化输出 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@nginx ~]# printf "%s\n" 1 2 3 41234[root@nginx ~]#[root@nginx ~]# printf "%f\n" 1 2 3 41.0000002.0000003.0000004.000000#.2f 表示保留两位小数[root@nginx ~]# printf "%.2f\n" 1 2 3 41.002.003.004.00[root@nginx ~]# printf "(%s)" 1 2 3 4;echo(1)(2)(3)(4)[root@nginx ~]# printf " (%s) " 1 2 3 4;echo "" (1)  (2)  (3)  (4) [root@nginx ~]# printf "(%s)\n" 1 2 3 4(1)(2)(3)(4)[root@nginx ~]# printf "%s %s\n" 1 2 3 41 23 4[root@nginx ~]# printf "%s %s %s\n" 1 2 3 41 2 34  #%-10s 表示宽度10个字符,左对齐[root@nginx ~]# printf "%-10s %-10s %-4s %s \n" 姓名 性别 年龄 体重 小明 男 20 70 小红 女 18 50姓名     性别     年龄 体重 小明     男        20   70 小红     女        18   50 #将十进制的17转换成16进制数[root@nginx ~]# printf "%X" 1711[root@nginx ~]##将十六进制C转换成十进制[root@nginx ~]# printf "%d\n" 0xC12[root@nginx ~]# VAR="welcome to here";printf "\033[31m%s\033[0m\n" $VARwelcometohere[root@nginx ~]# VAR="welcome to here";printf "\033[31m%s\033[0m\n" "$VAR"welcome to here[root@nginx ~]#

2.9 算术运算

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

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

*  /  %  multiplication, division, remainder, %表示取模,即取余数,示例:9%4=1,5%3=2+ -   addition, subtractioni++ i--  variable post-increment and post-decrement++i --i  variable pre-increment and pre-decrement= *= /= %= += -= <<= >>= &= ^= |=      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 ORexpr?expr:expr       conditional operatorexpr1 , expr2     comma

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

实现算术运算:

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

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

$RANDOM   取值范围:0-32767

案例:

#生成 0 - 49 之间随机数[root@nginx ~]# echo $[$RANDOM%50]40#随机字体颜色[root@nginx ~]# echo -e "\033[1;$[RANDOM%7+31]mhello\033[0m"hello[root@nginx ~]#

增强型赋值:

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

格式:

let varOPERvalue

案例:

[root@nginx ~]# let i=10*2[root@nginx ~]# echo $i20[root@nginx ~]# ((j=i+10))[root@nginx ~]# echo $j30

#自增,自减

let var+=1

let var++

let var-=1

let var--

[root@nginx ~]# unset i j ; i=1; let j=i++; echo "i=$i,j=$j"i=2,j=1[root@nginx ~]# unset i j ; i=1; let j=++i; echo "i=$i,j=$j"i=2,j=2

案例:

[root@nginx ~]# expr 2 \* 36[root@nginx ~]#[root@nginx ~]# echo "scale=3;20/3"|bc6.666[root@nginx ~]# i=10[root@nginx ~]# j=20[root@nginx ~]# declare -i result=i*j[root@nginx ~]# echo $result200[root@nginx ~]#

2.10 逻辑运算

true, false

1,真0,假

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

1 与 1 = 11 与 0 = 00 与 1 = 00 与 0 = 0

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

1 或 1 = 11 或 0 = 10 或 1 = 10 或 0 = 0

非:!

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

异或:^

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

1 ^ 1 = 01 ^ 0 = 10 ^ 1 = 10 ^ 0 = 0

案例:

[root@nginx ~]# true[root@nginx ~]# echo $?0[root@nginx ~]# false[root@nginx ~]# echo $?1[root@nginx ~]# ! true[root@nginx ~]# echo $?1[root@nginx ~]# ! false[root@nginx ~]# echo $?0[root@nginx ~]# x=10;y=20;temp=$x;x=$y;y=$temp;echo x=$x,y=$yx=20,y=10[root@nginx ~]# x=10;y=20;x=$[x^y];y=$[x^y];x=$[x^y];echo x=$x,y=$yx=20,y=10

短路运算

短路与

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

2.11 条件测试命令

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

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

条件测试命令

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

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

帮助:

[root@nginx ~]# type [[ 是 shell 内嵌[root@nginx ~]# help [[: [ 参数... ]    估值条件表达式。        是内嵌命令 "test" 的同义词,但是最后一个参数必须是    字符 `]',以匹配起始的 `['。[[ ... ]]: [[ 表达式 ]]    执行条件命令。        根据条件表达式 EXPRESSION 的估值返回状态0或1。表达式按照    `test' 内嵌的相同条件组成,或者可以有下列操作符连接而成:          ( EXPRESSION )	返回 EXPRESSION 表达式的值      ! EXPRESSION		如果 EXPRESSION表达式为假则为真,否则为假      EXPR1 && EXPR2	如果 EXPR1 和 EXPR2 表达式均为真则为真,否则为假      EXPR1 || EXPR2	如果 EXPR1 和 EXPR2 表达式中有一个为真则为真,否则为假        当使用 `==' 和 `!=' 操作符时,操作符右边的字符串被用作模式并且执行一个    匹配。当使用 `=~' 操作符时,操作符右边的字符串被当作正则表达式来进行    匹配。        操作符 && 和 || 将不对 EXPR2 表达式进行估值,如果 EXPR1 表达式足够确定    整个表达式的值。        退出状态:    根据 EXPRESSION 的值为0或1。[root@nginx ~]# help test...省略...

2.11.1 变量测试

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

案例:

[root@nginx ~]# unset x[root@nginx ~]# test -v x[root@nginx ~]# echo $?1[root@nginx ~]#[root@nginx ~]# x=10[root@nginx ~]# test -v x[root@nginx ~]# echo $?0[root@nginx ~]# y=[root@nginx ~]# test -v y[root@nginx ~]# echo $?0#注意 [ ] 中括号里面输入前和输入后需要空格,否则会报下面错误[root@nginx ~]# [-v y]-bash: [-v: 未找到命令        [root@nginx ~]# [ -v y ][root@nginx ~]# echo $?0[root@nginx ~]#

2.11.2 数值测试

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

案例:

[root@nginx ~]# i=10[root@nginx ~]# j=8[root@nginx ~]# [ $i -lt $j ][root@nginx ~]# echo $?1[root@nginx ~]# [ $i -gt $j ][root@nginx ~]# echo $?0[root@nginx ~]# [ i -gt j ]-bash: [: i: 期待整数表达式[root@nginx ~]#

算术表达式比较

==   相等!=   不相等<= >= < >

案例:

[root@nginx ~]# x=10;y=10;(( x == y ));echo $?0[root@nginx ~]# x=10;y=20;(( x == y ));echo $?1[root@nginx ~]# x=10;y=20;(( x != y ));echo $?0[root@nginx ~]# x=10;y=10;(( x != y ));echo $?1[root@nginx ~]# x=10;y=20;(( x > y ));echo $?1[root@nginx ~]# x=10;y=20;(( x < y ));echo $?0

2.11.3 字符串测试

test和 [ ]用法

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

[[]] 用法

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

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

案例:使用 [ ]

[root@nginx ~]# unset str[root@nginx ~]# [ -z "$str" ][root@nginx ~]# echo $?0[root@nginx ~]# str=""[root@nginx ~]# [ -z "$str" ][root@nginx ~]# echo $?0[root@nginx ~]# str=" "[root@nginx ~]# [ -z "$str" ][root@nginx ~]# echo $?1[root@nginx ~]#[root@nginx ~]#str=" "[root@nginx ~]#[ -z "$str" ][root@nginx ~]#echo $?1[root@nginx ~]#[ -n "$str" ][root@nginx ~]#echo $?0[root@nginx ~]#unset str[root@nginx ~]#[ -n "$str" ][root@nginx ~]#echo $?1[root@nginx ~]#[ "$str" ][root@nginx ~]#echo $?1[root@nginx ~]#str=magedu[root@nginx ~]#[ "$str" ][root@nginx ~]#echo $?0[root@nginx ~]#str=nihao[root@nginx ~]#[ "$str" ][root@nginx ~]#echo $?0[root@nginx ~]#str1=nihao[root@nginx ~]#str2=wohao[root@nginx ~]#[ $str1 = $str2 ][root@nginx ~]#echo $?1[root@nginx ~]#str2=nihao[root@nginx ~]#[ $str1 = $str2 ][root@nginx ~]#echo $?0

案例:在比较字符串时,建议变量放在“ ”中

[root@nginx ~]#[ "$NAME" ][root@nginx ~]#NAME="I love linux"[root@nginx ~]#[ $NAME ]-bash: [: love: binary operator expected[root@nginx ~]#[ "$NAME" ][root@nginx ~]#echo $?0[root@nginx ~]#[ I love linux ]-bash: [: love: binary operator expected

案例:[[ ]] 和通配符

[root@nginx ~]#FILE="a*"[root@nginx ~]#echo $FILEa*[root@nginx ~]#[[ $FILE == a* ]][root@nginx ~]#echo $?0[root@nginx ~]#FILE="ab"[root@nginx ~]#[[ $FILE == a* ]][root@nginx ~]#echo $?0[root@nginx ~]#FILE="a*"                #[[]]中如果不想使用通配符*,只想表达*本身,可以用" "引起来[root@nginx ~]#[[ $FILE == a"*" ]][root@nginx ~]#echo $?0[root@nginx ~]#FILE="ab"[root@nginx ~]#[[ $FILE == a"*" ]][root@nginx ~]#echo $?1#[[]]中如果不想使用通配符*,只想表达*本身,也可以使用转义符[root@nginx ~]#[[ $FILE == a\* ]][root@nginx ~]#echo $?1[root@nginx ~]#FILE="a\b"[root@nginx ~]#[[ $FILE == a\* ]][root@nginx ~]#echo $?1[root@nginx ~]#FILE="a*"[root@nginx ~]#[[ $FILE == a\* ]][root@nginx ~]#echo $?0#通配符?[root@nginx ~]#FILE=abc[root@nginx ~]#[[ $FILE == ??? ]][root@nginx ~]#echo $?0[root@nginx ~]#FILE=abcd[root@nginx ~]#[[ $FILE == ??? ]][root@nginx ~]#echo $?1#通配符[root@nginx ~]#NAME="linux1"[root@nginx ~]#[[ "$NAME" == linux* ]][root@nginx ~]#echo $?0[root@nginx ~]#[[ "$NAME" == "linux*" ]][root@nginx ~]#echo $?1[root@nginx ~]#NAME="linux*"[root@nginx ~]#[[ "$NAME" == "linux*" ]][root@nginx ~]#echo $?0#结论:[[ == ]] == 右侧的 * 做为通配符,不要加“”,只想做为*, 需要加“” 或转义

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

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

案例:使用 [[ ]] 判断文件后缀

#通配符[root@nginx ~]#FILE=test.log[root@nginx ~]#[[ "$FILE" == *.log ]][root@nginx ~]#echo $?0[root@nginx ~]#FILE=test.txt[root@nginx ~]#[[ "$FILE" == *.log ]][root@nginx ~]#echo $?1[root@nginx ~]#[[ "$FILE" != *.log ]][root@nginx ~]#echo $?0#正则表达式[root@nginx ~]#[[ "$FILE" =~ \.log$ ]][root@nginx ~]#echo $?1[root@nginx ~]#FILE=test.log[root@nginx ~]#[[ "$FILE" =~ \.log$ ]][root@nginx ~]#echo $?0

案例:判断合法的非负整数

[root@nginx ~]#N=100[root@nginx ~]#[[ "$N" =~ ^[0-9]+$ ]][root@nginx ~]#echo $?0[root@nginx ~]#N=Nihaolinux10[root@nginx ~]#[[ "$N" =~ ^[0-9]+$ ]][root@nginx ~]#echo $?1

案例:判断合法IP

[root@nginx ~]#IP=1.2.3.4[root@nginx ~]#[[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]][root@nginx ~]#echo $?0[root@nginx ~]#IP=1.2.3.4567[root@nginx ~]#[[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]][root@nginx ~]#echo $?1[root@nginx ~]#[[ $IP =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]][root@nginx ~]#echo $?1

2.11.4 文件测试

存在性测试

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

案例:

[root@nginx ~]#[ -a /etc/nologin ] [root@nginx ~]#echo $?1[root@nginx ~]#! [ -a /etc/nologin ] [root@nginx ~]#echo $?0[root@nginx ~]#[ -d /etc ][root@nginx ~]#echo $?0[root@nginx ~]#[ -d /etc/issue ][root@nginx ~]#echo $?1[root@nginx ~]#[ -L /bin ][root@nginx ~]#echo $?0[root@nginx ~]#[ -L /bin/ ][root@nginx ~]#echo $?1

文件权限测试:

-r FILE:是否存在且可读-w FILE: 是否存在且可写-x FILE: 是否存在且可执行-u FILE:是否存在且拥有suid权限-g FILE:是否存在且拥有sgid权限-k FILE:是否存在且拥有sticky权限

注意:最终结果由用户对文件的实际权限决定,而非文件属性决定

案例:

[root@nginx ~]#[ -w /etc/shadow ] [root@nginx ~]#echo $?0[root@nginx ~]#[ -x /etc/shadow ] [root@nginx ~]#echo $?1[root@nginx ~]#[ -w test.txt ][root@nginx ~]#echo $?0[root@nginx ~]#chattr +i test.txt [root@nginx ~]#lsattr test.txt----i-------------- xiaoming.txt[root@nginx ~]#[ -w test.txt ][root@nginx ~]#echo $?1[root@nginx ~]#chattr -i test.txt [root@nginx ~]#[ -w test.txt ][root@nginx ~]#echo $?0

文件属性测试

-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

未完待续~~

标签: #nginx shell