shell脚本的学习和使用

Posted 两片空白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell脚本的学习和使用相关的知识,希望对你有一定的参考价值。

目录

前言

 shell脚本编程注意事项​​​​​​​

第一个shell脚本——Hello world

shell脚本的变量

       定义变量

        使用变量

        只读变量

         删除变量

         变量类型

shell的字符串

Shell数组

 流程控制语句

        if分支语句

        case选择语句

        循环语句 

                标准for语句

                 for...in循环语句

         while循环语句

         select语句

   函数

介绍

传参和使用:

返回值:

函数库


前言

        shell:我们知道linux并不是一个可视化的操作系统,如果直接使用起来,成本比较高。而shell是一个命令行解释器,是用户与linux之间的桥梁,用户只需要输入命令,通过shell,解释成对应linux可以识别的命令。

        Linux 中的 shell 有很多种类,常用的几种:

        1. Bourne Shell(/usr/bin/sh 或/bin/sh)

        2. Bourne Again Shell(/bin/bash)

        3. C Shell(/usr/bin/csh)

        4. K Shell(/usr/bin/ksh)

        5. Shell for Root(/sbin/sh)

        使用最多的是bash,也是shell默认的命令行解释器。

        shell脚本:shell是用C语言编写的,shell脚本则是为shell编写的脚本程序。实际上,shell脚本就是一条一条linux命令组合起来,加上一些语法,为了实现一个目的。

        在linux命令行编写命令,可以说也是再编写shell脚本

 shell脚本编程注意事项

  • shell脚本文件的命名一般以英文小写,大写,后缀以.sh结尾
  • shell编程的用'#'表示注释
  • shell编程必须以 #!/bin/bash 开头
  • shell脚本的变量不能以数字,特殊符号开头,可以使用下划线,但是不能是用破折号

第一个shell脚本——Hello world

        建立一个.sh文件,在里面编写如下内容:

         执行shell脚本有两种方式:

  • 给.sh文件加上可执行的权限
chmod +x first.sh

./first.sh #执行shell脚本
  • 利用bash解释,将.sh文件作为bash的参数
/bin/bash first.sh

shell脚本的变量

       定义变量

        定义变量,变量名不需要叫'$'符号。定义变量有两种方式。

  • 直接定义
a=1

 注意:以这种方式命名的变量类型默认是字符串类型。

  • 使用declare命令,格式为 declare [+/-] [选项] 变量名

        其中 '-' 表示给变量加上特定属性,'+' 表示取消变量的特定属性。选项有一下几种:

#!/bin/bash 
 
a=1 #字符串类型
b=2
sum1=$a+$b
echo $sum1 

declare -i x=2 #整数类型
declare -i y=3
declare -i sum2
sum2=$x+$y
echo $sum2

        注意点:

  • 变量名和等号之间不能有空格
  • 变量命名只能使用英文字母(大写或者小写),数字和下划线,首个字母不能以数字和特殊符号开头。
  • 变量名中间不能有空格
  • 不能使用标点符号
  • 不能使用shell关键字

        使用变量

        使用一个变量,需要在变量前加一个'$'符号。

#!/bin/bash 

#echo "hello world!"

hello="hello world!"

echo $hello 
echo $hello

        如下使用''大括号是为了帮助解释器识别边界范围。如下,如果不加'',解释器会将helloworld当作一个变量。

#!/bin/bash 

hello="hello "
echo "$helloworld"

        只读变量

        使用readonly命令可以将变量定义为只读变量,只读变量不能被修改。相当于其他编程语言的常量。

         删除变量

        使用unset 命令可以删除变量。变量删除后,不能再被使用。

         变量类型

shell存在三种变量,系统变量,环境变量,局部(用户)变量。

  • 系统变量:主要是用于对参数判断和命令返回值判断时使用,系统变量详解如下:

$0 		shell本身文件名;
$n 		当前脚本的第n个参数,n=1,2,…9;
$* 		当前脚本的所有参数(不包括程序本身);
$# 		当前脚本的参数个数(不包括程序本身);
$? 		令或程序执行完后的状态,返回0表示执行成功;
$$ 		程序本身的PID号。

  • 环境变量:所有的程序,包括 shell 启动的程序,都能访问环境变量,有些程序需要环 境变量来保证其正常运行。必要的时候 shell 脚本也可以定义环境变量。

PATH  		命令所示路径,以冒号为分割;
HOME  		打印用户家目录;
SHELL 		显示当前Shell类型;
USER  		打印当前用户名;
ID    		打印当前用户id信息;
PWD   		显示当前所在路径;
TERM  		打印当前终端类型;
HOSTNAME    显示当前主机名;
PS1         定义主机命令提示符的;
HISTSIZE    历史命令大小,可通过 HISTTIMEFORMAT 变量设置命令执行时间;
RANDOM      随机生成一个 0 至 32767 的整数;
HOSTNAME    主机名
  • 局部变量:用户在脚本中定义的变量

shell的字符串

  • 介绍
    • shell脚本是用C语言写的,不难得到,字符串底层是用字符数组保存的。但是shell脚本的字符串并不是以'\\0'结尾。
    • 在shell脚本中'*'和'@'是通配符。

        字符串是 shell 编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好

用了),字符串可以用单引号,也可以用双引号,也可以不用引号。

        单引号:任何字符都会原样输出。没有转义,也不能使用变量。

        双引号:可以使用转义和变量。

         

  • 拼接字符串

  • 获取字符串长度:使用'#'

  •  提取子字符串

        注意:shell脚本的字符串是从下标0开始的。

$string:start # 从左边start位置开始,从左到右截取剩余所有的字符串
$string:start:length # 从左边start位置开始,从左到右截取length长度的字符串
$string:0-start # 从右边start位置开始,从左到右截取剩余所有的字符串
$string:0-start:length # 从右边start位置开始,从左到右截取length长度的字符串
$string#chars # 从左开始匹配第一个chars字符串,截取其右边的字符串
$string##chars # 从左开始匹配最后一个chars字符串,截取其右边的字符串
$string%chars # 从右开始匹配第一个chars字符串,截取其左边的字符串
$string%%chars # 从右开始匹配最后一个chars字符串,截取其左边的字符串

  •  查找子字符串:使用 expr命令,可以进行四则运算和字符串操作,expr index是在字符串中查找字符 

        shell脚本反引号(``)作用:反引号包含内的字符会被作为shell命令来进行输出,并返回结果,主要是为了获得返回结果。如果想直接执行,写到脚本中就可以了。

  • 替换字符串
$string/substring/replacement # 使用$replacement, 来代替第一个匹配的$substring
$string//substring/replacement # 使用$replacement, 代替所有匹配的$substring
$string/#substring/replacement # 如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
$string/%substring/replacement # 如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring

  •  判断与默认值
$str:-DEFAULT # 如果str为空, 那么就以DEFAULT作为返回值
$str:=DEFAULT # 如果str为空, 那么就以DEFAULT作为返回值, 并将str赋值为DEFAULT
$str:+OTHER # 如果str不为空, 那么就以OTHER作为返回值
$str:?ERR_MSG # 如果str为空, 那么输出报错信息ERR_MSG并推出程序

Shell数组

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

        类似于C语言,数组下标有0开始编号。获取数组元素需要通过下标。下标可以是整数或者算术表达式,其值应当大于等于0。

  • 定义数组

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

#!/bin/bash
 
arr1=(1 2 3 4 5)

#单独定义数组分量
declare -a arr2
arr2[0]=a
arr2[1]=b
arr3[5]=e
  • 获取数组元素

        需要使用下标的方式来访问。并且必须加上花括号。

         使用"@"或者"*"可以访问数组的所有元素。

  •  获取数组长度

        获取数组长度的方式和获取字符串长度的方式相同。

  •  数组遍历

数组遍历有三种方式:

               1. 标准for循环。在bash中适用,在sh中不适用

                 2. for in形式

                 3. while循环

 流程控制语句

        if分支语句

  • 格式
//单分子
if [ 条件表达式 ];then
    语句
fi

//双分支
if [ 条件表达式 ];then
    语句1
else
    语句2
fi

//多分支
if [ 条件表达式 ];then
    语句1
elif [ 条件表达式 ];then
    语句2
elif [ 条件表达式 ];then
    语句3
else
    语句4
fi
  • 常用逻辑判断运算符
-f	 	判断文件是否存在 eg: if [ -f filename ];
-d	 	判断目录是否存在 eg: if [ -d dir     ];
-eq		等于,应用于整型比较 equal;
-ne		不等于,应用于整型比较 not equal;
-lt		小于,应用于整型比较 letter;
-gt		大于,应用于整型比较 greater;
-le		小于或等于,应用于整型比较;
-ge 	大于或等于,应用于整型比较;
-a		双方都成立(and) 逻辑表达式 –a 逻辑表达式;
-o		单方成立(or) 逻辑表达式 –o 逻辑表达式;
-z		空字符串;
-x      是否具有可执行权限
||      单方成立;
&&      双方都成立表达式。
  • 例子

1. 使用单分支语句判断进程是否运行

        $1: 获得传入脚本第一个参数。

        $():脚本里使用,为执行括号里的命令。作用相当于反引号。

        grep -v 不显示含有后面的字符串 

        grep -c 返回显示函数 

2. 判断学生成绩等级

        case选择语句

        case语句主要用于对多个选择条件进行匹配输出,与if elif结构相似,通常用于脚本传递输入参数,打印输出结果和内容。

  • 结构:以case ... in 开头,以esac结束。

        注意:

        1. 每一个模式后需要以')'反括号结尾,执行的命令后,需要以双引号结尾';;'

        2. esac,每一次都会执行。

#找到对应模式,执行命令
case 模式名 in 
    模式1)
        命令
        ;;
    模式2)
        命令
        ;;

#以上模式执行完后,都会执行这里的命令
esac
  • 例子:使用shell脚本来启动和杀死一个进程。

首先:编写一个程序,让其进入死循环。

 接下来编写shell 脚本

        read 命令作用:将硬件键盘输入到对应变量中。

        read -p:打印后面字符串 

 #!/bin/bash 

read -p "please select start|stop test.c# " way
case $way in
   start)
     gcc test.c -o test
     ./test &
     ;;
   stop)
     num=`ps -axj | grep test | grep -vc grep`
     echo $num
     if [ $num -eq 1 ];then
       testpid=`pidof test`
       echo $testpid
       kill -9 $testpid
       rm -f test
     else
       echo "test proc is not run"
     fi 
     ;;
   #利用通配符来做其他选择判断
   *)                                                                                                                                                                                   
     echo "select way error"
     ;;
esac
   echo "shell script run success"

        循环语句 

                标准for语句

        在shell脚本中支持一种和C语言for循环写法差不多的形式。但是在bash中适用,在sh解释器中不适用。

格式:

for (( ...里面写法和C语言类似... ))
do
    命令
done

                 for...in循环语句

                在bash和sh解释器中都适用

        格式:variable 表示变量,value_list 表示取值列表,in 是 Shell 中的关键字。意思就是,顺序获取到在in右边元素列表的元素,直到取完。

for variable in value_list
do
    statements
done

         获取元素列表的方式有下面几种方式:

  • 在in右边直接给出各各值,每个值之间用空格隔开。

        遍历数组,实际就是将所有数组元素中间空格隔开,放到in右边。 

  • 给出一个取值范围。
start..end

  •  使用命令的执行结果

        用到$()或者反引号``来执行命令获得结果。

        seq命令,获得某个范围内的整数,并且可以设置步长。

        seq 2 2 100,是从2开始,每次加2,到100结束。

         while循环语句

格式:

while 判断语句
do
    命令
done

例子:

  • 死循环

  •  打印数字

 注意:shell脚本同样支持break和continue关键字,作用同C语言。

         select语句

格式:

select param in list
do
    语句
done

        select命令是一个无限循环,所以注意需要设置好退出循环条件。  select命令中,一般需要配合case命令。

        注意输入是select选项的序号。

        select一般结合PS3使用, PS3会在select选项后打印PS3的值。

   函数

介绍

        shell脚本中支持将一组命令集或语句形成一个可用块,成为shell函数。shell函数只需要定义一次,可以重复使用,提高代码的利用率。

结构:

#语法
funcname()
    命令1
    命令2
    ...


#调用
funname

传参和使用:

        传参直接在掉哦那个函数后面加上需要的参数,参数之间用空格分隔

        在函数里面使用参数可以使用 

  • $n:获得第n个参数
  • $#:获得传递参数的个数
  • $@或者$*:可以一次性获得全部参数

返回值:

        函数可以看作是一条命令,函数里如果使用了return关键字,可以使用$?,获取到函数执行的状态码,即return的值。

        但是,状态码只有8位,最大值为255。如果超过了255,会被截断。

 如果想获取到的值不截断

  • shell脚本的变量(不加local的)默认是全局有效,可以在里面进行操作,外面也能得到。

  • 在函数体内使用echo输出,在函数体外赋值

 消除一个顾虑:

        在函数体内如果使用echo,在函数体外,没有接收,会被打印。

        如果在函数体外接收,不会打印。

注意点:

  • shell脚本中的变量默认是全局有效,如果想定义局部变量,需要加上关键字local。

函数库

以上是关于shell脚本的学习和使用的主要内容,如果未能解决你的问题,请参考以下文章

2018-05-29 Linux学习

shell脚本学习笔记12-正则表达式

Linux学习总结(五十七) shell脚本1

Shell脚本入门及搭建yum仓库脚本

shell

编写shell脚本自动生成开头注释简介