Shell脚本编写

shell使用

shell脚本类似于我们在Windows中编写的批处理文件,它的扩展名是.bat,比如我们启动Tomcat(后面的课程我们会详细讲解)的时候经常启动的startup.bat,就是Windows下的批处理文件。而在Linux中,shell脚本编写的文件是以.sh结尾的。比如Tomcat下我们经常使用startup.sh来启动我们的Tomcat,这个startup.sh文件就是shell编写的。

1shell入门

1.1、什么是shell

Shell 脚本(shell script),是一种为 shell 编写的脚本程序。又称 Shell 命令稿、程序化脚本,是一种计算机程序使用的文本文件,内容由一连串的 shell 命令组成,经由 Unix Shell 直译其内容后运作。

Shell 被当成是一种脚本语言来设计,其运作方式与解释型语言相当,由 Unix shell 扮演命令行解释器的角色,在读取 shell 脚本之后,依序运行其中的 shell 命令,之后输出结果。利用 shell 脚本可以进行系统管理,文件操作等。在 Unix 及所有的系统中,如 Linux、FreeBSD 等操作系统,都存在 shell 脚本。依照 Unix shell 的各种不同类型,shell 脚本也有各种不同方言。在 DOS、OS/2、Microsoft Windows 中的批处理文件,跟 shell 脚本有类似的功能。

1.2、shell环境

java需要虚拟机解释器, 同理 shell脚本也需要解释器,Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。

Linux 的 Shell 种类众多,常见的有:

- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)

- 等等……

我使用的是Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell

1.3编写第一个shell

现在,我们打开文本编辑器(我们也可以使用 vi/vim 命令来创建文件),新建一个文件 czbk.sh,扩展名为 sh(sh代表shell):

#!/bin/bash  --- 指定脚本解释器
echo "测试shelll !"

//写shell的习惯 第一行指定解释器

//文件是sh为后缀名

//括号成对书写

//注释的时候尽量不用中文注释。不友好。

//[] 括号两端要要有空格。  [ neirong ]

//习惯代码索引,增加阅读性

//写语句的时候,尽量写全了,比如if。。。

注意:
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
echo 命令用于向窗口输出文本。

2 shell注释

2.1、单行注释

以#开头的行就是注释,会被解释器忽略。

通过每一行加一个#号设置多行注释,如下:

#--------------------------------------------
# 这是一个注释
#--------------------------------------------
##### 开始 #####
#
#
# 这里可以添加脚本描述信息
# 
#
##### 结束  #####

2.2、多行注释

多行注释可以使用以下格式:

:<<!
注释内容...
注释内容...
注释内容...
!

3、shell变量

3.1、定义变量:

variable_name="czbk"

变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:

- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
- 不能使用bash里的关键字(可用help命令查看保留关键字)。

有效的 Shell 变量名示例如下:
RUNOOB
LD_LIBRARY_PATH
_var
var2
无效的变量命名:
?var=123
user*name=runoob

3.2、使用变量

使用一个定义过的变量,只要在变量名前面加美元符号即可,如:

variable_name="czbk"
echo $variable_name
echo ${variable_name}

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,这里我们推荐给所有变量加上花括号,这也是一个好的编程习惯。

已定义的变量,可以被重新定义,如:

your_name="tom"
echo $your_name
your_name="frank"
echo $your_name
这样写是合法的,但注意,第二次赋值的时候不能写
$your_name="frank",使用变量的时候才加$。

3.3、只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

下面的例子尝试更改只读变量,结果报错:

#!/bin/bash
myUrl="https://www.baidu.com"
readonly myUrl
myUrl="https://cn.bing.com/"

3.4、删除变量

使用 unset 命令可以删除变量。语法:

unset variable_name

变量被删除后不能再次使用。unset 命令不能删除只读变量。

示例如下

#!/bin/sh
myUrl="https://www.baidu.com"
unset myUrl
echo $myUrl

如上面的shell脚本,我们定义了一个myUrl变量,通过unset删除这个变量,然后通过echo进行输出,结果是就是为空,没有任何的结果输出。

4、Shell 字符串

4.1、单引号

str='this is a string variable'

单引号字符串的限制:

- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

4.2、双引号

your_name='frank'
str="Hello,  \"$your_name\"! \n"
echo -e $str

双引号的优点:

- 双引号里可以有变量
- 双引号里可以出现转义字符

5、shell数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。

5.1、定义数组

在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。如下:

#数组名=(值1 值2 ... 值n)
#例如:
array_name=(value0 value1 value2 value3)
#通过下标定义数组中的其中一个元素:
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
#可以不使用连续的下标,而且下标的范围没有限制。

5.2、读取数组

读取数组元素值的一般格式是:

${数组名[下标]}
例如:
valuen=${array_name[n]}
使用@符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}

5.3、获取数组的长度

获取数组长度的方法与获取字符串长度的方法相同,例如:

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}

6、shell运算符

Shell 和其他编程一样,支持包括:算术、关系、布尔、字符串等运算符。原生 bash不支持简单的数学运算,但是可以通过其他命令来实现,例如expr。expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

6.1、算数运算符

val=`expr 2 + 2`
echo "相加之后的结果为:" $val

注意:表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2。完整的表达式要被 **`** 包含,注意不是单引号。下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:

运算符

说明

举例

+

加法

expr $a + $b 结果为 30。

-

减法

expr $a - $b 结果为 -10。

*

乘法

expr $a \* $b 结果为 200。

/

除法

expr $b / $a 结果为 2。

%

取余

expr $b % $a 结果为 0。

=

赋值

a=$b 将把变量 b 的值赋给 a。

==

相等。用于比较两个数字,相同则返回 true。

[ ​b ] 返回 false。

!=

不相等。用于比较两个数字,不相同则返回 true。

[ ​b ] 返回 true。

注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b]是错误的,必须写成[ $a == $b ]。

#! /bin/bash

#g=(a b c d e f)

#echo "数组下标为2的数据为:" ${g[2]}

#echo  "数组所有数据为:"  ${#g[@]}

#echo  "数组所有数据为:"   ${#g[*]}

:<<EOF

val= `expr 2 + 2`

echo "相加之后的结果为:" $val

EOF

a=4

b=20

echo “加法运算”  `expr $a + $b`

echo “减法运算”  `expr $a - $b`

echo “乘法运算,注意*号前面需要反斜杠” ` expr $a \* $b`

echo “除法运算”  `expr  $b / $a`

((a++))

echo "a = $a"

c=$((a + b))

d=$[a + b]

echo "c = $c"

echo "d = $d"

上面的shell命令#开头的为单行注释

:<<EOF 开头和EOF结尾的为多行注释

6.2、字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":

运算符

说明

举例

=

检测两个字符串是否相等,相等返回 true。

[ ​b ] 返回 false。

!=

检测两个字符串是否相等,不相等返回 true。

[ ​b ] 返回 true。

-z

检测字符串长度是否为0,为0返回 true。

[ -z $a ] 返回 false。

-n

检测字符串长度是否为0,不为0返回 true。

[ -n "$a" ] 返回 true。

$

检测字符串是否为空,不为空返回 true。

[ $a ] 返回 true。

字符串运算符实例如下

a="abc"
b="efg"

if [ $a = $b ]
then
   echo "$a = $b : a 等于 b"
else
   echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"
else
   echo "$a != $b: a 等于 b"
fi

6.3、关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:

运算符

说明

举例

-eq

检测两个数是否相等,相等返回 true。

[ ​b ] 返回 false。

-ne

检测两个数是否不相等,不相等返回 true。

[ ​b ] 返回 true。

-gt

检测左边的数是否大于右边的,如果是,则返回 true。

[ ​b ] 返回 false。

-lt

检测左边的数是否小于右边的,如果是,则返回 true。

[ ​b ] 返回 true。

-ge

检测左边的数是否大于等于右边的,如果是,则返回 true。

[ ​b ] 返回 false。

-le

检测左边的数是否小于等于右边的,如果是,则返回 true。

[ ​b ] 返回 true。

关系运算符

a=10
b=20

if [ $a -eq $b ]
then
   echo "$a -eq $b : a 等于 b"
else
   echo "$a -eq $b: a 不等于 b"
fi
if [ $a -ne $b ]
then
   echo "$a -ne $b: a 不等于 b"
else
   echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
   echo "$a -gt $b: a 大于 b"
else
   echo "$a -gt $b: a 不大于 b"
fi
if [ $a -lt $b ]
then
   echo "$a -lt $b: a 小于 b"
else
   echo "$a -lt $b: a 不小于 b"
fi
if [ $a -ge $b ]
then
   echo "$a -ge $b: a 大于或等于 b"
else
   echo "$a -ge $b: a 小于 b"
fi
if [ $a -le $b ]
then
   echo "$a -le $b: a 小于或等于 b"
else
   echo "$a -le $b: a 大于 b"
fi

6.4、布尔运算符

下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:

运算符

说明

举例

!

非运算,表达式为 true 则返回 false,否则返回 true。

[ ! false ] 返回 true。

-o

或运算,有一个表达式为 true 则返回 true。

[ ​b -gt 100 ] 返回 true。

-a

与运算,两个表达式都为 true 才返回 true。

[ ​b -gt 100 ] 返回 false。

布尔运算符实例如下(还是采用之前的例子test-shell.sh ):

a=10
b=20

if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"
else
   echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
   echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
   echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
   echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
   echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
   echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
   echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi

6.5、逻辑运算符

假定变量 a 为 10,变量 b 为 20:

运算符

说明

举例

&&

逻辑的 AND

[[ $a -lt 100 && $b -gt 100 ]] 返回 false

||

逻辑的 OR

[[ $a -lt 100 \|\| $b -gt 100 ]] 返回 true

逻辑运算符实例如下

a=10
b=20

if [[ $a -lt 100 && $b -gt 100 ]]
then
   echo "返回 true"
else
   echo "返回 false"
fi

if [[ $a -lt 100 || $b -gt 100 ]]
then
   echo "返回 true"
else
   echo "返回 false"
fi

7 shell流程控制

7.1、if 语句:

主要用于判断,相当于java se中的if

if condition
then
    command1 
    command2
    ...
    commandN 
fi

比如,我们现在通过前面学习的知识查找一个进程,如果进程存在就打印true

if [ $(ps -ef | grep -c "ssh") -gt 1 ]; 
    then echo "true"; 
fi

注意
末尾的fi就是if倒过来拼写

7.2、if else 语句:

主要用于判断,相当于java se中的if else

if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi

上接上面的例子,如果找不到sshAAA进程,我们就打印false

if [ $(ps -ef | grep -c "sshAAA") -gt 1 ];
     then echo "true";  
else echo "false"; 
fi

执行效果如下

7.3、if else-if else 语句:

主要用于判断,相当于java se中的if else-if else

if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi

以下实例判断两个变量是否相等

a=10
b=20
if [ $a == $b ]
then
   echo "a 等于 b"
elif [ $a -gt $b ]
then
   echo "a 大于 b"
elif [ $a -lt $b ]
then
   echo "a 小于 b"
else
   echo "没有符合的条件"
fi

7.4、for 循环

主要用于循环,相当于java se中的for循环

for循环格式为

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

顺序输出当前列表中的字母:

for loop in A B C D E F G 
do
    echo "顺序输出字母为: $loop"
done

7.5、while循环

主要用于循环,相当于java se中的while循环

while循环用于不断执行一系列命令,也用于从输入文件中读取数据 

语法格式为

while condition
do
    command
done

以下是一个基本的while循环,测试条件是:如果int小于等于10,那么条件返回真。int从0开始,每次循环处理时,int加1。 

#!/bin/bash
int=1
while(( $int<=10 ))
do
    echo "输出的值为:"$int
    let "int++"
done

7.6、case ... esac语句

主要用于分支条件选择,相当于java se中的switch case循环 

case ... esac与其他语言中的 switch ... case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号 ;;表示 break,即执行结束,跳出整个 case ... esac 语句,esac(就是 case 反过来)作为结束标记。

case ... esac 语法格式如下:

case 值 in
模式1)
    command1
    command2
    command3
    ;;
模式2)
    command1
    command2
    command3
    ;;
*)
    command1
    command2
    command3
    ;;
esac

case 后为取值,值可以为变量或常数。

值后为关键字 in,接下来是匹配的各种模式,每一模式最后必须以右括号结束,模式支持正则表达式。

下面通过v的值进行case--esac

v="czbk"
case "$v" in
   "czbk") echo "java"
   ;;
   "baidu") echo "baidu 搜索"
   ;;
   "google") echo "google 搜索"
   ;;
esac

执行效果如下

8、 shell函数

函数语法如下:

[ function ] funname [()]

{
    action;

    [return int;]

}

注意:
 - 1、可以使用function fun() 定义函数,也可以直接fun() 定义,不带任何参数。
 - 2、函数参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255

下面我们将定义一个函数,并发生函数调用

#!/bin/bash

czbk(){
    echo "这是第一个函数!"
}
echo "-----这里是函数开始执行-----"
czbk
echo "-----这里是函数执行完毕-----"

下面,我们定义一个带有return语句的函数:

function czbk(){
    echo "对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum 和 $anotherNum !"
    return $(($aNum+$anotherNum))
}
czbk
echo "输入的两个数字之和为 $? !"

注意:
函数返回值在调用该函数后通过 $? 来获得。
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值