欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux中的shell脚本

程序员文章站 2024-02-19 14:43:53
...

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))
}

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

$* 和 [email protected] 的区别:
不加""取值都一样,可以将所有的值作为一个参数列表
加""取值时:
$* : 所有参数是一个字符串,即一个元素"1 2 3"
[email protected] : 所有参数分别是多个字符,即可以做一个参数列表"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 : 直接完成