Linu进阶-Shell编程入门上 hf

一, Shell编程入门

  1. 为什么大数据需要学习shell编程
  • 需要看懂运维人员编写的Shell程序;
  • 管理集群(编写集群时间同步的crontab脚本, 定时维护数据库等等);
  1. 什么是shell?
  • shell是一个命令行解释器,它接收应用程序/用户的命令, 然后调用操作系统内核, 它是用户使用操作系统的桥梁;
  • shell编程就是对一堆Linux命令的逻辑化处理;
  1. Shell环境

二, 第一个shell脚本

要点:

  1. 脚本以 #!/bin/bash 开头
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c1QaOFAC-1621604345413)(2021-05-19-11-09-31.png)]

  2. 脚本被赋予执行权限

  3. 也可以不赋予执行权限, 而使用 sh xx.sh来执行脚本(不推荐)

  4. Shell脚本文件以.sh为后缀, 但是也可以.txt等后缀

  5. 脚本可相对路径执行, 也可绝对路径执行

脚本编写如下:

#!/bin/bash
    echo "Hello, are u sb?"

图示如下:

注意:

三, shell变量

3.1 变量的一些约束和命名规则

变量名和等号之间不能有空格; 同时变量的命名有以下规则:
- 命名只能使用英文字母, 数字和下划线, 不能以数字开头;
- 变量中间不存在空格, 可以使用下划线;
- 不能使用标点符号;
- 不能使用bash中的关键字
- 变量名一般为全大写

举个栗子:

[注意]

  1. 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。

  2. 变量的值如果有空格,需要使用双引号或单引号括起来。

3.2 shell变量的种类

按照变量的作用域, shell变量被分为了 局部变量, 环境变量, shell变量

运行shell时,会同时存在这三种变量:

  1. 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

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

    • 自定义环境变量

  3. shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行


tips: 在shell里如何使用多行注释?

3.3 对变量的操作

3.3.1 使用变量(${变量名})

使用一个定义过了的变量, 我们需要在变量前面加上美元符号;

举个栗子:

在这里插入图片描述

变量名外面的花括号是可选的, 其主要作用是为了帮助解释器识别变量的边界;

3.3.2 使变量只读(readonly 变量名)

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

  • 举个栗子:

3.3.3 删除变量(unset 变量名)

使用unset命令可以删除变量;
注意: 只读变量无法被删除

  • 举个栗子

只读变量无法被删除:

3.3.4 将linux命令的结果赋给变量(重要)

两种方法

  1. 使用反引号, 例如: A=`ls `
  2. $(命令), 例如: A=$(ls)

图示如下:


3.4 Shell位置参数变量

[定义]
在Linux的命令行中, 当一条命令或脚本执行时, 后面可以跟多个参数, 我们使用位置参数变量来表示这些参数;

其中, $0表示命令行本身, $1代表执行脚本时添加的第一个参数, $2代表添加的第二个参数, 以此类推.
当参数个数超过10个时, 就要用大括号把这个数字括起来, 例如, ${10}道代表第10个参数, ${14}代表第14个参数.

图示如下:


在shell中可以识别的位置参数变量及含义如下表所示:

位置参数变量作用
$nn为数字, $0代表命令本身, $1-$9代表1-9个参数, 10以上的参数需要用大括号包含, 如 ${10}
$*代表命令行中所有的参数, 把所有的参数看作是一个整体
$@代表命令行中所有的参数, 不过 $@把每个参数区别对待
$#代表命令行中所有参数的个数

图示如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4f2BHgam-1621604345465)(2021-05-20-12-31-39.png)]

3.5 shell预定义变量

[定义]
预定义变量是在Shell一开始时就定义的变量,这一点和默认环境变量有些类似. 不同的是, 预变量不能重新定义, 用户只能根据Shell的定义来使用这些变量;

严格来说, 位置参数变量也是预定义变量的一种, 只是位置参数变量的作用比较统一, 所以我们把位置参数变量单独划分为一类变量;

预定义变量

|预定义变量|作用|
|$?| 表示最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。|
|$$|当前进程的进程号(PID)|
|$!|后台运行的最后一个进程的进程号(PID)|

图示如下:

$? 的使用

$$ 和 $!的使用


============================ 7.14

四, 运算符

4.1 算数运算符

[基本语法]

  1. 不使用expr的运算写法, " $((运算式))" 或 " $[运算式] "
  2. expr $m + $n 注意expr, 运算式, 运算符号之间的空格一个都不能少
  3. expr 加+, 减-, 乘*, 除/, 取余%
  4. 我们可以对比复习一下命令结果的传递, 使用反引号 `命令`, 或者是 $(命令)
  5. 再对比复习一下, 使用某个变量, 命令是 变 量 名 < / k b d > , 如 果 是 帮 助 解 释 器 识 别 边 界 还 需 写 成 < k b d > 变量名</kbd>, 如果是帮助解释器识别边界还需写成<kbd> </kbd>,<kbd>{变量名}

算术运算符

[案例实操]

在这里插入图片描述
在这里插入图片描述

4.2 关系运算符

[常用运算符和用法]

关系运算符只支持数字, 不支持字符串, 除非字符串的值是数字;
下表列举了常用的关系运算符, 假定变量a为10, b为20;

运算符说明举例
-eq (equal等于)检测两个数是否相等, 相等返回true[ $a -eq $b ] 返回false
-ne (not equal不等于)检测两个数是否不相等, 不相等返回true[ $a -ne $b ]返回true
-gt (greater than大于)检测左边的数是否大于右边的,是返回true[ $a -gt $b ] 返回false
-lt (less than小于)检测左边的数是否小于右边的, 如果是,则返回true[ $a -lt $b ]返回true
-ge (greater equal大于等于)检测左边的数是否大于等于右边的, 是则返回true[ $a -ge $b ]返回true
-le (less equal小于等于)检测左边的数是否小于等于右边的,是则返回true[ $a -ls $b ] 返回false

[案例实操]


五, 条件判断

[基本语法]

# 注意: condition前后一定要有空格!!!!
    [ condition ]

[常用判断条件]

  1. 两个整数之间比较
  • 字符串比较 =
  • 数字比较:
  1. 按照文件权限进行判断

  2. 按照文件类型判断

[案例实操]

  1. 判断test文件是否存在
    在这里插入图片描述

  2. 判断字符是否相同

  3. 判断文件是否存在,是否是一个目录

  1. 多条件判断(&& 表示前一条命令命令执行成功时,才执行后一条命令, || 表示上一条命令执行失败后, 才执行下一条命令)

六, 流程控制

6.1 if判断

[基本语法]

  1. if
if [ 条件判断式 ]
then 
    command1
    command2
    ...
fi
  1. if else
if [ 条件判断式 ]
then
    command1
    command2
    ...
else
    command
fi
  1. if else-if else
if [ 条件判断式1 ]
then
    command1
elif [ 条件判断式2 ]
then
    command2
else
    comandN
fi

注意:

  1. 条件判断式不要忘了两边的空格, if后面也得有空格
  2. 对于shell程序, 规定流程控制的分支不能为空, 例如: 如果 else 分支没有语句执行,就不要写这个 else。
    [案例实操]
  1. 编写一个shell程序, 如果输入的参数,大于等于60, 则输出"及格了", 如果小于60, 则输出"不及格"


  1. 判断a,b两个变量的大小关系

6.2 case…esac语句

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

[基本语法]

casein
模式1)
    command1
    command2
    ....
;;
模式2)
    command1
    command2
    ...
;;
esac
  1. case 工作方式如上所示, 取值后面必须为单词in, 每一模式必须以右括号结束. case 值 in
  2. 取值将检测匹配的每一个模式. 一旦模式匹配, 则执行完匹配模式相应命令后不再继续其他模式. 如果无一匹配模式, 使用星号 * 捕获该值, 再执行后面的命令;

[案例实操]

  1. 下面的脚本提示输入 1 到 4,与每一种模式进行匹配:

  1. 下面的脚本匹配字符串:

    ![]](https://img-blog.csdnimg.cn/20210522111748383.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25tc0xMQ1NETg==,size_16,color_FFFFFF,t_70#pic_center)

6.3 for循环

[基本语法 1.]

for ((初始值;循环控制条件;变量变化))
    do
        循环程序段
    done

[基本语法 2.]

for 变量 in 值1 值2 值3 ...
    do  
        对变量循环的程序段
    done

[案例实操]

  1. 从1加到10

  1. 输入1,2,3,4,5

  2. 输入字符串

$*$@的辨析

先看一个借助for循环实现的栗子:

  1. 使用 #*作为循环的对象

  2. 使用 #@作为循环的对象

总结如下:

  1. #*#@都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 $2 …$n的形式输出所有参数。
  2. 当它们被双引号“”包含时,“$*”会将所有的参数作为一个整体,以“$1 $2 …$n”的形式输出所有参数;“$@”会将各个参数分开,以“$1” “$2”…”$n”的形式输出所有参数。

6.4 while循环

[基本语法]

while [ 条件判断式 ]
    do
        循环程序段
    done

[案例实操]

  1. 从1加到100

七, read读取控制台输入

[基本语法]

read (选项) (参数)

选项:
-p: 指定读取值时的提示符;
-t: 指定读取值时等待的时间(秒);
参数:
变量: 指定读取值的变量名;

[案例实操]

八, 函数

8.1 系统函数

shell 编程和其它编程语言一样,有系统函数,也可以自定义函数。系统函数中,我们这里就先介绍下面两个

8.1.1 basename

[基本用法和用途]

功能: 常用于获取文件名(即文件路径最后一个正斜杠’/'后面的内容)
基本语法:

basename [pathname] [suffix]

选项:
suffix 为后缀,如果 suffix 被指定了,basename 会将 pathname 或 string 中的 suffix 去掉。

[案例实操]


![]](https://img-blog.csdnimg.cn/20210522112222510.png#pic_center)

8.1.2 dirname

[基本用法和用途]
功能: 常用于返回路径部分(即文件路径中除了最后一个正斜杠’/'前面的部分)
基本语法:

dirname 文件绝对路径

[案例实操]

8.2 自定义函数

[基本语法]

function 函数名(){
    程序段
    return 返回值
}
  • function 是shell中的关键字, 专门用来定义函数;
  • return 返回值 表示函数的返回值, 其中 return 是shell关键字, 专门在函数中返回一个值, 这个字段可写可不写;

注意: shell中函数的两种简化写法如下

简化写法1:

# 省略 function 关键字
函数名(){
    程序段
    [return value]
}

简化写法2:

#如果写了function关键字, 也可以省略函数名后的小括号
function name{
    程序段
    [return value]
}

对 返回值的说明

函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)

[函数的调用]

调用shell函数时可以给它传递参数, 也可以不传递. 如果不传递参数, 直接给出函数名字即可;

name

如果传递参数, 那么多个参数之间以空格分隔:

name param1 param2 param3

和其它编程语言不同的是,Shell 函数在定义时不能指明参数,但是在调用时却可以传递参数,并且给它传递什么参数它就接收什么参数

Shell 也不限制定义和调用的顺序,你可以将定义放在调用的前面,也可以反过来,将定义在调用的后面。

[案例实操]

  1. 一个简单的打印函数, 并且函数在调用时传入了参数

  2. 定义一个函数,计算所有参数的和

$@表示函数的所有参数,$?表示函数的退出状态(返回值)

posted @ 2022-05-26 20:31  青松城  阅读(147)  评论(0编辑  收藏  举报