读完学会shell语法,shell脚本80%已经学会

3 shell语法讲解

3.1 shell运算讲解

3.1.1 运算符的讲解

3.1.2 shell运算方式的讲解

3.1.2.1 $(())运算

[root@m01 test_init] # a=1

[root@m01 test_init] # b=1

[root@m01 test_init] # echo $a+$b

1+1

[root@m01 test_init] # echo $((c=a+b))

2

3.1.2.2. let运算(只能计算整数)

[root@m01 ~] # a=1

[root@m01 ~] # b=1

[root@m01 ~] # echo $d

 

[root@m01 ~] # let d=a+b

[root@m01 ~] # echo $d

2

[root@m01 ~] # a=1.5

[root@m01 ~] # let d=a+b

-bash: let: 1.5: syntax error: invalid arithmetic operator (error token is ".5")

[root@m01 ~] #

3.1.2.3 expr计算(expr只能计算整数,并且中间需要有空格)

[root@m01 ~] # a=1

[root@m01 ~] # b=4

[root@m01 ~] # expr c=a+b                expr计算错误

c=a+b

[root@m01 ~] # expr c = a + b

expr: non-integer argument                expra,b识别成参数,参数不是整数造成的

[root@m01 ~] # expr c =1+2

expr: syntax error                    expr语法错误

 

[root@m01 ~] # expr 1 + 2                expr正确的计算

3

[root@m01 ~] # expr 1 * 3                为什么这样计算也有问题

expr: syntax error

[root@m01 ~] # expr 1 \* 3                计算方式

3

3.1.2.3.1 expr乘法为什么需要将乘号转义下

  • 原因:因为expr在计算的时候将*认成了通配符*造成的,使用echo则知道

3.1.2.3.2 expr 0+0的错误想法

  • 问题:0+0=0,对的啊,为什么返回值是错误的
  • 原因:我们可以在加一个数字来进行计算,会发现语法错误报错提示

  • 结论:通过这个可以知道expr在计算的时候,不能是0和null

 

3.1.2.4 bc方法计算

3.1.2.4.1 整数计算

[root@m01 ~] # echo 3+2 | bc

5

[root@m01 ~] #

 

[root@m01 ~] # echo 5*3 | bc

15

[root@m01 ~] # echo 2^3|bc

8

[root@m01 ~] #

3.1.2.4.2 小数计算
  • -l            Define the standard math library.(定义标准数学计算方法)

[root@m01 ~] # echo "5/3" | bc

1                            发现bc在计算的时候只会将整数输出来,默认小数不进行输出

[root@m01 ~] #

[root@m01 ~] #

[root@m01 ~] # echo "5/3" | bc -l        

1.66666666666666666666

[root@m01 ~] #

[root@m01 ~] #

3.1.2.4.3 进制计算

[root@m01 ~] # echo "obase=16;1234"|bc            10进制转16进制

4D2

[root@m01 ~] # echo "obase=8;1234"|bc            10进制转8进制

2322

[root@m01 ~] # echo "obase=2;1234"|bc            10进制转2进制

10011010010

[root@m01 ~] # echo "obase=10;10000111"|bc        10进制转10进制(测试是不是输入的默认是10进制)

10000111

[root@m01 ~] # echo "obase=2;10000111"|bc            10进制转2进制

100110001001011011101111

3.1.2.5 awk计算方法

3.1.2.5.1 awk最普通的计算方法

[root@m01 ~] # awk 'BEGIN{print 3*2}'

6

[root@m01 ~] #

3.1.2.5.2 awk利用变量的计算方法

[root@m01 ~] # a=1

[root@m01 ~] # b=2

[root@m01 ~] # awk -v n=$b 'BEGIN{print n,n**3,n*n}'

2 8 4

[root@m01 ~] #

3.1.2.5.3 awk利用变量计算方法

[root@m01 ~] # a=1

[root@m01 ~] # b=2

[root@m01 ~] # awk -v n1=$a -v n2=$b 'BEGIN{print n1,n1**n2,n1*n2}'

1 1 2

[root@m01 ~] #

3.1.2.6 $[]计算方法

[root@m01 ~] # echo $((3/2))

1

[root@m01 ~] # echo $[3/2]                    (())一样,[]只是一对

1

3.2 shell条件测试语句的讲解

3.2.1 文件相关表达式

3.2.1.1 常见的表达式

表达式

含义

例子

-d

directory目录是否存在

[root@m01 ~] #

[root@m01 ~] # [ -d /oldboy/ ] && echo "true" || echo "false"

true

[root@m01 ~] # cd /oldboy

[root@m01 oldboy] #

-f

file文件是否存在

[root@m01 oldboy] # [ -f /oldboy/1.txt ] && echo "true" || echo "false"

true

[root@m01 oldboy] # ll /oldboy/1.txt

-rw-r--r-- 1 root root 12 Oct 1 11:50 /oldboy/1.txt

[root@m01 oldboy] #

-r

read文件是否存在,并且是否具有读权限

[root@m01 ~] # [ -r /oldboy/bb ] && echo true || echo "false"

false

[root@m01 ~] # ll /oldboy/bb

ls: cannot access /oldboy/bb: No such file or directory

[root@m01 ~] #

-w

write文件是否存在,并且是否具有写权限

[root@m01 ~] # ll /oldboy/bb

ls: cannot access /oldboy/bb: No such file or directory

[root@m01 ~] # [ -w /oldboy/bb ] && echo true || echo "false"

false

-x

execute文件是否存在,并且是否具有执行权限

[root@m01 ~] # ll /oldboy/bb

ls: cannot access /oldboy/bb: No such file or directory

[root@m01 ~] # [ -x /oldboy/bb ] && echo true || echo "false"

false

-s

size文件里面的内容是否是空的

[root@m01 ~] # [ -s /oldboy/aa ] && echo true || echo "false"

false

[root@m01 ~] # cat /oldboy/aa

[root@m01 ~] #

-e

exits文件是否存在

[root@m01 ~] # cat /oldboy/aa

[root@m01 ~] # [ -e /oldboy/aa ] && echo true || echo "false"

true

[root@m01 ~] #

-L

symlink文件是否存在,并且是不是软链接

[root@m01 ~] # [ -L /etc/rc.local ] && echo true || echo "false"

true

[root@m01 ~] # ll /etc/rc.local

lrwxrwxrwx 1 root root 13 Sep 20 11:25 /etc/rc.local -> rc.d/rc.local

[root@m01 ~] #

f1 -nt f2

文件f1是不是新于f2

[root@m01 ~] # touch aa.txt

[root@m01 ~] # touch bb.txt

[root@m01 ~] # [ /root/aa.txt -nt /root/bb.txt ] && echo true || echo "false"

false

f1 -ot f2

文件f1是不是旧于f2

[root@m01 ~] # touch aa.txt

[root@m01 ~] # touch bb.txt

[root@m01 ~] # [ /root/aa.txt -ot /root/bb.txt ] && echo true || echo "false"

true

3.2.2 字符串的比较(提示:字符串要加双引号"" )

表达式

含义

例子

-n

not zero字符串不是空的,则返回true

[root@m01 ~] # aa=0

[root@m01 ~] # [ -n "aa" ] && echo "$aa" || echo false

0

[root@m01 ~] #

-z

zero字符串是空的,则返回true

[root@m01 ~] # aa=0

[root@m01 ~] # [ -z "aa" ] && echo "$aa" || echo false

false

"A"=="B"

字符串A等于字符串B则返回true

[root@m01 ~] # aa=0

[root@m01 ~] # bb=2

[root@m01 ~] # [ "aa" == "bb" ] && echo "$aa" || echo false

false

"A"!="B"

字符串A不等于字符串B,则返回true

[root@m01 ~] # aa=0

[root@m01 ~] # bb=2

[root@m01 ~] # [ "aa" != "bb" ] && echo "$aa" || echo false

0

[root@m01 ~] #

 

3.2.3 整数的比较

3.2.3.1 []比较

表达式

含义

例子

-gt

greate than大于

[root@m01 ~] # [ 3 -gt 2 ] && echo yes || echo no

yes

 

-ge

 

greate equal 大于等于

[root@m01 ~] # [ 3 -ge 3 ] && echo yes || echo no

yes

[root@m01 ~] #

 

-lt

 

less than 小于

[root@m01 ~] # [ 3 -lt 2 ] && echo yes || echo no

no

[root@m01 ~] #

 

-le

 

less equal 小于等于

[root@m01 ~] # [ 3 -le 2 ] && echo yes || echo no

no

[root@m01 ~] #

 

-ne

 

not equal 不等于

[root@m01 ~] # [ 3 -ne 2 ] && echo yes || echo no

yes

[root@m01 ~] #

 

-eq

 

equal 等于

[root@m01 ~] # [ 3 -eq 4 ] && echo yes || echo no

no

3.2.3.2 (())或者[[]]比较(不常用)

 

表达式

含义

例子

>

大于

[root@m01 ~] # ((3>2)) && echo yes || echo no

yes

 

>=

 

大于等于

[root@m01 ~] # ((2>=3)) && echo yes || echo no

no

 

<

 

小于

[root@m01 ~] # ((3<2)) && echo yes || echo no

no

[root@m01 ~] #

 

<=

 

小于等于

[root@m01 ~] # ((2<=2)) && echo yes || echo no

yes

[root@m01 ~] #

 

!=

 

不等于

[root@m01 ~] # ((2!=2)) && echo yes || echo no

no

[root@m01 ~] #

 

== or =

 

等于

[root@m01 ~] # ((2==2)) && echo yes || echo no

yes

[root@m01 ~] #

3.2.4 逻辑符号的比较

3.2.4.1 []比较方法

表达式

含义

例子

(())比较方法

 

!

 

not取反

[root@m01 ~] # [ ! -d /etc/aa ] && echo "yes" || echo "no"

yes

[root@m01 ~] #

 

!

 

-a

 

and并且的关系

[root@m01 ~] # [ ! -d /etc/aa -a -f /etc/hosts ] && echo "yes" || echo "no"

yes

[root@m01 ~] #

 

 

&&

 

-o

 

or或者的关系

[root@m01 ~] # [ -d /etc/aa -o -f /etc/host ] && echo "yes" || echo "no"

no

[root@m01 ~] #

 

||

3.3 if语句的讲解

3.3.1 if语句的语法

3.3.1.1 单分支结构

3.3.1.1.1 语法

if [ ];then

命令

fi

 

 

if [ ]

then

命令

fi

3.3.1.1.2 例子

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

if [ 3 -gt 2 ]

then

echo "true"

fi

[root@m01 test_init] # sh para_0.sh

true

[root@m01 test_init] #

3.3.1.2 双分支结构

3.3.1.2.1 语法

if [ ]

then

echo cmd1

else

echo cmd2

fi

3.3.1.2.2 例子

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

if [ 3 -lt 2 ]

then

echo "true"

else

echo "false"

fi

[root@m01 test_init] # sh para_0.sh

false

[root@m01 test_init] #

3.3.1.3 多分枝结构

3.3.1.3.1 语法

if []

then

echo ""

elif []

then

echo ""

else

echo ""

fi

3.3.1.3.2 例子

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

read -p "please input num " num

 

if [ $num -lt 2 ]

then

echo "true"

elif [ $num -lt 10 ]

then

echo "el_true"

else

echo "false"

fi

[root@m01 test_init] # sh para_0.sh

please input num 12

false

[root@m01 test_init] # sh para_0.sh

please input num 9

el_true

[root@m01 test_init] #

3.4 while语句的讲解

3.4.1 语法讲解

3.4.1.1 有限的循环

while <条件表达式>

do

命令1

done

3.4.1.2 无限的循环

[root@m01 test_init] # while true

do

条件

done

3.4.1.3 while读取的方法

[root@m01 test_init] # while read 变量

do

echo ""

done<文件

3.4.2 例子

3.4.2.1 有限循环的例子

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

a=$1

while [ $a -lt 2 ]

do

echo "aa"

let a++;

done

[root@m01 test_init] # sh para_0.sh 0

aa

aa

[root@m01 test_init] #

3.4.2.2 无限循环的例子

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

while true

do

echo "aa"

done

[root@m01 test_init] #

3.4.2.3 read的例子(暴力破解超过10次就给禁止掉)

[root@m01 test_shell] # vim pojie_ip.sh

#!/bin/bash

file_txt=/server/scripts/count.txt

awk '$6~/Failed/{print $(NF-3)}' /var/log/secure | sort -nr | uniq -c > $file_txt

while read key value

do

if [ $key -gt 10 -a `iptables -nvL | grep -wc "$value"` -eq 0 ]

then

iptables -A INPUT -s $value -p tcp --dport 22 -j DROP

fi

done<$file_txt

 

3.5 case语句的讲解

3.5.1 case语法讲解

case "变量" in

1)

指令1...

;;

2)

指令2...

;;

*)

指令3...

esac

 

case "你有什么条件" in

有钱)

白富美结婚

;;

有权)

白富美结婚

;;

有爹)

白富美

;;

有才有能力有潜力)

先谈个对象看看

;;

*)

洗洗睡吧

esac

3.5.2 case例子讲解

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

read -p "please input num " num

case $num in

1) echo "you input num is 1" ;;

2) echo "you input num is 2" ;;

*) echo "you input num null " ;;

esac

[root@m01 test_init] # sh para_0.sh

please input num 2

you input num is 2

[root@m01 test_init] # sh para_0.sh 6

please input num 6

you input num null

[root@m01 test_init] #

3.6 函数的讲解

3.6.1 函数的概念

将程序中经常能使用的代码组合起来,并且起个函数名称

3.6.2 函数的语法格式

function 函数名() {

指令集

return n

}

 

function 函数名 {

指令集

return n

}

 

函数名() {

指令集

return n

}

3.6.3 函数的例子

3.6.3.1 函数通常使用

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

fun() {

aa=12

echo $aa

}

fun

[root@m01 test_init] # sh para_0.sh

12

[root@m01 test_init] #

3.6.3.2 函数传参方式使用

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

a1=$1

echo $a1

fun() {

aa=$2

echo $2

}

fun

[root@m01 test_init] # sh para_0.sh 1 2                2个参数为啥只识别了脚本里面的,函数里面的没有

1

 

[root@m01 test_init] #

 

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

a1=$1

echo $a1

fun() {

a2=$1

echo $a2

}

fun 66

 

[root@m01 test_init] # sh para_0.sh 1                发现2个参数都已经出来了

1

66

[root@m01 test_init] #

 

  • 结论:函数里面的参数信息和shell里面的参数信息是不一致的,函数里面的信息只对函数本身起作用,属于局部的,shell里面的参数信息是全局的,整个shell都可以使用

3.7 颜色和vimrc的讲解

3.7.1 颜色的语法

\e[字体格式;颜色 文字信息\e[0m

 

\033[字体格式;颜色 文字信息\033[0m

 

\E[字体格式;颜色 文字信息\E[0m

 

3.7.2 颜色的例子

3.7.3 对每个组成进行讲解

  • \e也可以使用\033替代。
  • [1数字1表示加粗显示(这个位置可以加不同的数字代表不同的意思,详细信息可man console_codes获得) 。
  • 31m表示为红色字体,这个位置可以换不同的数字,以代表不同的意思。
  • "aa":表示待设置的内容。
  • [0m表示关闭所有属性,这个位置可以换不同的数字,以代表不同的意思

 

man console_codes

3.7.4 vimrc的讲解

  • 当前用户生效~/.vimrc
  • 全部用户生效/etc/vimrc

3.8 for语句的讲解

3.8.1 for语法格式

for 变量 in 变量取值的列表

do

指令

done

 

for 变量 in 1 2 3 4 5 {a..z} `seq 10` `ls /etc`

do

指令

done

 

C循环使用

for((i=1;i<=10;i++))             只是用来对数字进行循环,shell数组进行循环

do

指令

done

3.8.2 for的例子

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

for i in `seq 10`

do

echo $i

done

[root@m01 test_init] # sh para_0.sh

1

2

3

4

5

6

7

8

9

10

[root@m01 test_init] #

 

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

n=0

sum=0

for i in `seq 10`

do

((sum=sum+i))

done

echo $sum

[root@m01 test_init] # sh para_0.sh

55

[root@m01 test_init] #

3.8.3 循环控制

名称

含义

例子

continue (n)

终止本次循环,开始下一次的循环,n表示结束本次循环,直接跳到第n次循环

[root@m01 test_init] # vim para_0.sh

 

#!/bin/bash

 

for i in `seq 10`

do

for j in `seq 10`

do

if [ $j -eq 6 ] && continue 2

then

echo $j

else

echo $i $j

fi

done

done

break (n)

终止这次循环并且以后的循环,直接跳出,n表示结束循环,调到指定的n次循环

[root@m01 test_init] # vim para_0.sh

#!/bin/bash

 

for i in `seq 10`

do

for j in `seq 10`

do

for k in `seq 10`

do

[ $k -eq 6 ] && break 2

echo $i $j $k

done

done

done

exit n

退出脚本,n返回值

[root@m01 test_init] # cat para_0.sh

#!/bin/bash

 

for i in `seq 10`

do

if [ $i -eq 9 ]

then

exit 0

fi

done

[root@m01 test_init] # echo $?

0

[root@m01 test_init] #

return n

返回数值,n放在脚本或者函数的最后,判断函数的返回值

[root@m01 test_init] # vim para_0.sh

#!/bin/bash

 

fun() {

for i in `seq 10`

do

if [ $i -eq 9 ]

then

return 0

fi

done

}

fun

 

 

3.9 shell数组讲解

3.9.1 语法

3.9.1.1 通过[]方式来获取

[root@m01 ~] # ip[1]=10.0.0.61

[root@m01 ~] # ip[2]=10.0.0.51

[root@m01 ~] # ip[3]=10.0.0.41

[root@m01 ~] # echo ${#ip[*]}

3

[root@m01 ~] # echo ${ip[*]}

10.0.0.61 10.0.0.51 10.0.0.41

[root@m01 ~] #

3.9.1.2 通过()方式来获取

[root@m01 ~] # ip=(10.0.0.61 10.0.0.51 10.0.0.41)

[root@m01 ~] # echo ${ip[*]}

10.0.0.61 10.0.0.51 10.0.0.41

[root@m01 ~] # echo ${ip[0]}

10.0.0.61

[root@m01 ~] #

 

[root@m01 ~] # ip=(`cat /etc/hosts`)

[root@m01 ~] # echo ${ip[*]}

127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.16.1.81 firewalld 172.16.1.5 lb01 172.16.1.6 lb02 172.16.1.7 web01 www.oldboy.com 172.16.1.8 web02 172.16.1.9 web03 172.16.1.51 db01 172.16.1.31 nfs01 172.16.1.41 backup 172.16.1.61 m01 172.16.1.71 zabbix

[root@m01 ~] # echo ${#ip[*]}

33

[root@m01 ~] #

3.9.2 例子

[root@m01 ~] # ip=(10.0.0.61 10.0.0.51 10.0.0.41)

[root@m01 ~] # for i in ${ip[*]} ;do ping -c 1 -W1 $i ;done

posted @ 2020-01-07 20:14  HXX-LYX  阅读(552)  评论(0编辑  收藏  举报