shell脚本

208 阅读3分钟

1.1 什么是shell?

shell英文翻译过来是外壳的意思,作为计算机语言来理解可以认为它是操作系统的外壳。我们可以通过shell命令来操作和控制操作系统,比如Linux中的shell命令就包括ls、cd、pwd等等。 shell是站在内核的基础上编写的一个应用程序,它连接了用户和Linux内核,从而让用户能够更加便捷、高效、安全的使用linux内核,这其实就是shell的本质。 使用专业术语的说法来解释,Shell其实是一个命令解释器,它通过接受用户输入的Shell命令来启动、暂停、停止程序的运行或对计算机进行控制。 1.2 什么是shell脚本

shell脚本就是由Shell命令组成的执行文件,将一些命令整合到一个文件中,进行处理业务逻辑,脚本不用编译即可运行。它通过解释器解释运行,所以速度相对来说比较慢。 1.3 shell脚本的意义

我们在1.2中也解释道shell脚本其实就是shell命令组成的文件,shell脚本可以记录命令执行的过程和执行逻辑,以便以后重复执行,还可以批量、定时处理主机,方便管理员进行设置或者管理。 二、创建一个简单的Shell脚本 2.1 创建一个shell脚本文件

在创建shell脚本时,我们默认新建一个以.sh/.script结尾的文件,主要是为了让程序员更加快捷的辨认出该文件是一个shell脚本文件。 我们创建一个test.sh的shell脚本文件,其中具体内容为下: #!/bin/bash echo hello " # ”开头的就是注释,单行注释 <<EOF … EOF 或 :<<! … ! :多行注释 #!/bin/bash : 主要用于指定解释器 Linux中提供的shell解释器有: /bin/sh /bin/bash /usr/bin/sh /usr/bin/bash 2.2 运行一个Shell脚本

我们根据脚本文件是否具有可执行权限,将运行一个shell脚本的方法分为两大类。 2.2.1 脚本文件无执行权限 这种情况下我们有三种方式来运行脚本: 手动在环境中开启指定解释器:sh test.sh

直接在当前环境中运行的shell中运行脚本:. test.sh

直接在当前环境中运行的shell中运行脚本:source test.sh

2.2.2 脚本文件有执行权限 在这一部分由于我们假设脚本文件有可执行器权限,所以我们使用chmod +x test.sh为我们的test.sh文件增加了可执行权限。 我们知道当一个文件具有可执行权限时我们可以使用该文件的路径名直接运行该文件,有两种方式可以运行脚本: 1.绝对路径名运行脚本文件 绝对路径就是从根目录下开始记录文件路径名,是文件在计算机上真正存在的路径。(如果不知道你的文件路径名,可以在当前位置的shell中使用pwd查询当前所在位置)

2../相对路径名的格式运行脚本文件 相对路径是指以当前的文件作为起点,相较于当前目录的位置而被指向并且加以引用的文件资源。 比如我们知道test.sh文件的绝对路径为/home/westos/Desktop/textcpp/test.sh,那么当我们在testcpp文件夹中时,test.sh文件的相对路径为test.sh。 又因为.代表当前所在位置,故而为其实./test.sh其实就是该文件的绝对路径,只是表示的方式不同。

三、基本语法 3.1 变量

变量名其实就是一片内存区域的地址或者可以说是寻址符号,有了变量我们就可以使用一串固定的字符来表示不固定的目标。 3.1.1 变量类型 在shell中会同时存在三种类型变量。 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。 shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行 3.1.2 变量操作 创建普通变量:name=“test”,组要注意的是等号两边不能有空格。 创建局部变量:local name=“test”,使用local修饰的变量在函数体外无法访问,只能在函数体中使用。 创建只读变量:name=“only_read” -> readonly name,这种变量不可以被修改。 使用变量:echo name或者echoname或者echo {name} 删除变量:unset name,删除之后的变量无法被访问,需要注意无法删除只读变量。 3.1.3 字符串变量 3.1.3.1 字符串变量的创建 使用单引号创建:var='test'。 这种方式创建的变量只能原样输出,变量无效,我们可以借用c中的“字符串常量”的定义理解这种特性。除此以外,单引号中不能出现单独的单引号,转义也是不可以的。 使用双引号创建:var="my name is name",这种方式创建的字符串变量有效,也可以出现转义符。3.1.3.2拼接字符串字面量拼接str01="1""2"或者str01="1"2,这样就将12两个字符拼接在了一起。需要注意的是两个串之间不可以有空格。变量拼接str03={name}",这种方式创建的字符串变量有效,也可以出现转义符。 3.1.3.2 拼接字符串 字面量拼接 str01="1""2"或者str01="1"'2',这样就将1和2两个字符拼接在了一起。需要注意的是两个串之间不可以有空格。 变量拼接 str03={part01}part02str04={part02}或str04={part01}"end"或str05="part01{part01} {part02}"这三种方式都可以拼接字符串变量。 命令拼接 str02= date“end”,这里的date是一个shell命令,需要使用引用,具体如下: str02=date"end" 3.1.3.3 获取字符串长度 1.使用wc -L命令 wc -L可以获取到当前行的长度,因此对于单独行的字符串可以用这个简单的方法获取,另外wc -l则是获取当前字符串内容的行数。 echo "abc" |wc -L 2.使用expr length可以获取string的长度 expr length {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->str} 3.awk获取域的个数 但是如果大于10个字符的长度时是否存在问题需要后面确认 echo "abc" |awk -F "" '{print NF}' 4.通过awk+length的方式获取字符串长度 echo “Alex”|awk '{print length(0)}' 5.通过echo {#name}的方式 name=Alex echo {#name} 3.1.3.4 提取子字符串 1.如下方式: 代码 意义 {varible##*string} 从左向右截取最后一个string后的字符串 {varible#string} 从左向右截取第一个string后的字符串 {varible%%string*} 从右向左截取最后一个string后的字符串 {varible%string} 从右向左截取第一个string后的字符串 例,如下代码: MYVAR=foodforthought.jpgMYVAR=foodforthought.jpg echo {MYVAR##*fo} 运行结果为rthought.jpg 2.使用{varible:n1:n2} 截取变量varible从n1到n2之间的字符串,可以根据特定字符偏移和长度,来选择特定子字符串,如下代码: EXCLAIM=cowabungaEXCLAIM=cowabunga echo EXCLAIM:0:3运行结果最终显示cow3.1.4数组如果说变量是存储单个变量的内存空间,那么数组就是多个变量的集合,它存储多个元素在一片连续的内存空间中。在bash中,只支持一维数组,不支持多维数组。3.1.3.1数组定义与引用定义一个数组方式如下:数组名=(元素1元素2元素3...元素n)指定数组对应下标的元素进行赋值:数组名[下标]=值同时指定多个数组元素进行赋值:数组名=([下标1]=1[下标2]=2...[下标n]=n)引用数组对应下标的元素:{EXCLAIM:0:3} 运行结果最终显示cow。 3.1.4 数组 如果说变量是存储单个变量的内存空间,那么数组就是多个变量的集合,它存储多个元素在一片连续的内存空间中。在bash中,只支持一维数组,不支持多维数组。 3.1.3.1 数组定义与引用 定义一个数组方式如下: 数组名=(元素1 元素2 元素3 ... 元素n) 指定数组对应下标的元素进行赋值: 数组名[下标]=值 同时指定多个数组元素进行赋值: 数组名=([下标1]=值1 [下标2]=值2 ... [下标n]=值n) 引用数组对应下标的元素: {数组名[下标]} 3.1.3.2 遍历数组元素 使用for(或while循环)循环遍历数组元素: #!/bin/bash a=(1 2 3 4 5 6) for((i=0; i<10; i++)) do echo "a[i]=i]={a[i]}" done 除此以外我们还可以使用{a[]}或者{a[@]}来遍历数组元素,具体代码如下: #!/bin/bash a=(1 2 3 4 5 6) echo {a[]} echo {a[@]} 3.1.3.3 获取数组长度 我们可以使用#来获取数组长度,需要注意的是在shell脚本中我们越界访问数组时是不会报错的。 #!/bin/bash a=(1 2 3 4 5 6) echo {a[]} echo "a len: {#a[*]}" 我们先使用其获取数组中的元素后使用#获取元素个数即可。 3.1.3.4 合并数组 我们可以如下进行拼接: #!/bin/bash a=(1 2 3 4 5 6) b=("hello" "zhaixue.cc") c=({a[]} ${b[*]}) 这样我们就将两个数组拼接起来了。