Linux中的shell脚本

shell 脚本:通常指的是在linux版本服务器中编写的脚本。shell 脚本本看成用户和系统之间的沟通桥梁。

shell属于解释型语言。

解释器类型有:
/bin/sh
/bin/bash
/bin/ksh
/bin/csh
等。

常用和绝大多数linux内核系统默认使用bash

shell脚本运行方式:
1、授予脚本可执行的权限
chmod a+x ./first.sh  : 授予可执行权限
./first.sh  : 执行./first.sh脚本

2、使用解释器执行:
bash ./first.sh : 使用bash解释执行
sh ./first.sh : 使用sh解释执行


===========shell中的变量
变量定义:
class=gp1813

注意:
1、变量名不能使用数字开头
2、=号的前后不能有空格
3、变量命令尽量不要使用关键字。(使用set或者help查看)

变量赋值:
class=corder

只读变量(不能再readonly之后重新赋值):
readonly class  

删除变量:
unset class
直接把该行删除

变量的取值:
$class  或者 ${class}   :{}可以限定变量名称  
echo ${class}class,$classclass


变量类型:
局部变量:某个脚本或者是脚本中某个方法中的变量
环境变量:配置到全局环境变量配置文件或者是个人的环境变量配置文件中


字符串:shell中一个弱类型的语言,变量都值的类型几乎都是是字符串。
字符串拼接:
echo ${class}class

"" 、 '' 、`` 三者符号的区别:
"" : 双引号中的取值符号或者是其它转义符都能被识别
'' : 单引号中的所有的字符串将会被原样输出
`` : 反引号中的内容是可执行的linux命令。反引号有的时候可以使用$(())来替代
echo "${class}class"
echo '${class}class'
echo `date`  : 该句和下一句是等价的
echo $(date)


获取字符串的长度:
echo "class variable length: "${#class}


字符串的截取:
echo ${class:2:3}  : 从2角标开始,截取3个长度。角标从0开始


shell中的数组:
和c中的数组差不多一样,暂不支持二维数组,数组下标都是从0开始。
数组定义:
arr1=(1 2 3 4 5 6 9)
arr2=(
1
3
5
7
9
)
arr3[0]=2
arr3[2]=5
arr3[4]=666
 
数组赋值:
arr1[0]=100
arr2[0]=1000
arr3[0]=10000

取单个值和所有值:
echo $arr1
echo $arr2
echo $arr3
echo ${arr2[*]},${arr2[@]}
echo ${arr3[4]} : 取单个值

取数组的长度:
echo ${#arr3},${#arr3[*]},${arr3[100]}    当下标越界时不报异常


shell中的注释:
除脚本中的第一行#!/bin/bash等指定解释器语句外的几乎所有#都是注释。
单行注释:一个#
多行注释:每一行加#或者使用方法封装需要注释的行,并且不调用该方法即可


shell中的运算:
数学运算
+ - * / %

#!/bin/bash
echo "$1+$2"=`expr $1 + $2`
echo "$1-$2"=`expr $1 - $2`
echo "$1*$2"=`expr $1 * $2`
echo "$1/$2"=`expr $1 / $2`
echo "$1%$2"=`expr $1 % $2`

echo "$1+$2"=$(($1+$2))
echo "$1-$2"=$(($1-$2))
echo "$1*$2"=$(($1*$2))
echo "$1/$2"=$(($1/$2))
echo "$1%$2"=$(($1%$2))

运行脚本:
./math.sh 200 10

注意:
expr 是一个计算器工具命令,需要使用`` ,还需要注意空格
可以使用$(())来进行数学计算

关系运算
-eq -lt -le -ge -gt -ne = < <= >= > !=
 

#!/bin/bash
a=10
b=6
if [ $a -gt $b ]
then
echo "$a>$b"
fi
if [ $a -eq $b ]
then
echo "$a=$b"
fi
fi
if [ $a -le $b ]
then
echo "$a<=$b"
fi
if [ $a -ne $b ]
then
echo "$a!=$b"
fi

if (($a>$b))
then
echo "$a>$b"
fi


字符运算
=
!=
-z : 为0返回true,否则false
-n : 不为0返回true
str : 不为0返回true


file=/home/shell/math.sh
if [ -z $file ]
then
echo "$file is null"
else
echo "$file is not null"
fi

if [ -n $file ]
then
echo "$file is not null"
else
echo "$file is null"
fi

if [ $file ]
then
echo "$file is not null"
else
echo "$file is null"
fi

文件运算:
-d: 是否是目录
-f: 是否是文件
-r:
-w:
-x:
-e: 文件或者目录是否存在
-s: 大小是否为0,不为0返回true
 


filepath=/home/shell/math.sh
if [ -f $filepath ]
then
echo "$filepath is file"
fi

if [ -e $filepath ]
then
echo "$filepath is exists"
fi

if [ -x $filepath ]
then
echo "$filepath is execute"
fi

if [ -s $filepath ]
then
echo "$filepath length is not 0"
fi

布尔运算
!
-a : 逻辑与&&
-o : 逻辑或||

逻辑运算:&& ||   ,如果需要使用这种数学中的这种符号,需要使用双中括号或者圆括号。

if [[ $1 -gt $2 || $1 -eq $2 ]]
then
echo "$1>=$2"
fi

if [[ $1 -gt $2 -o $1 -eq $2 ]]
then
echo "$1>=$2"
fi

三元运算符:
[条件] && cmd1 || cmd2   条件满足,执行cmd1,不满足cmd2

[ 1 = 1 ] && echo "1=1" || echo "1!=1"

控制条件:
if []
then
cmd1
fi


if []
then
cmd1
else
cmd2
fi


if []
then
cmd1
elif []
then
cmd2
else

fi


if [];then cmd1;fi   写成一行

注意:
if后面需要有then
没有elseif,只有elif
每一个if都需要有fi结束
每一个控制体中都必须要有语句
if和[]中的空格需要严格注意。如果使用$(())可以不用注意空格
else后面不能跟then,否则报错

a=10
b=6
if [ $a -gt $b ]
then
echo "$a > $b"
elif [ $a -eq $b ]
then
echo "$a=$b"
else
echo "$a < $b"
fi

if(($a>$b))
then
echo "$a>$b"
fi

循环
for  while until
for i in 循环体
do
cmd...
done

for i in 1 2 3 ; do echo $i ; done
for i in `seq 1 10`
do
echo $i
done

basedir=/home/shell
for i in `ls $basedir`
do
echo $basedir/$i
done

while((循环体))
do
cmd...
done

i=0
while(($i<11))
do
echo $i
#i=`expr $i + 1`
let "i++"
done


i=0
while:  死循环
do
echo $i
#i=`expr $i + 1`
let "i++"
done
 

until 循环体
do
cmd...
done

echo "until==============="
j=0
until [ $j > 10 ]
do
echo $j
done

例子:取执行shell脚本文件后参数的时间,不管中间操作数有多少个,如果最后没有时间,则输出今天的时间

数据如形式如:

./for.sh -m fas -n 12 -d 2018-09-10
./for.sh -m fas -n 12 -d
./for -d 2018-09-10

date=
unitl [ $# -eq 0 ]
do
if [ $1'x' = '-dx' ]
then
shift
date=$1
fi
shift
done
echo $date

shell中支持case In模式匹配,类似switch case 
case 值 in
模式1)
cmd...
;;
模式2)
cmd...
;;
esac

shell中也支持continue和break

例子:

while:
do
echo "请输入一个1-10的数字:"
read num
case $num in
1|2|3|4|5|6|7|8|9|10)
echo "你输入的数字$num在1-10之间."
break
;;
*)
echo "你输入的数字$num不在1-10之间.清继续输入:"
continue
;;
esac
done

shell中的方法
[function] 方法名(){
方法体
}


无参数无返回值方法:

function fun1(){
echo "i am in function fun1."
}

echo "before Function invoke."
fun1
echo "after Function invoke."


带参数无返回值:

function fun2(){
echo "sum is:"$(($1+$2))
}
带参数,带返回值:

function fun3(){
echo "第1个参数:$1"
echo "第2个参数:$2"
echo "第9个参数:$9"
echo "第10个参数:$10"
echo "第10个参数:${10}"
echo "所有参数:$*"
echo "所有参数个数:$#"
return $(($1+$2))
}

$# :取参数的个数
$* : 取所有参数
$@ :取所有参数
$? : 取返回值.只能返回方法的退出代码(0-255之间)
$0 : 取运行当前脚本
$1-9 : 取第几个参数
${10} : 取第10个及以上的参数

$* 和 $@ 的区别:
不加""取值都一样,可以将所有的值作为一个参数列表
加""取值时:
$* : 所有参数是一个字符串,即一个元素"1 2 3"
$@ : 所有参数分别是多个字符,即可以做一个参数列表"1" "2" "3"


shell中的问价的引入:
source 文件的绝对路径
. 文件的绝对路径


shell中的调试:
sh -n ./for.sh : 检测for.sh语法是否有问题
sh -x ./for.sh : 查看for.sh的运行详细情况


sh -x ./for.sh : 按ctrl + z退出程序,然后分别按fg键(f键和g键)继续调试

断点调试:借助第三方的调试工具bashdb进行断掉调试

bashdb的命令:
l : 列出10行代码
n : 执行下语句
c 5: 一直运行n行
s 5: 单步运行多少次
b 5: 在5行打断点
del 5 : 删除5行的断点
q : 退出
R : 重新断点
finish : 直接完成
 

猜你喜欢

转载自blog.csdn.net/weixin_42474930/article/details/82632453