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

二, 第一个shell脚本
要点:
-  脚本以 #!/bin/bash 开头 
 ![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c1QaOFAC-1621604345413)(2021-05-19-11-09-31.png)]](https://img-blog.csdnimg.cn/20210521214057666.png#pic_center) 
-  脚本被赋予执行权限 
-  也可以不赋予执行权限, 而使用 sh xx.sh来执行脚本(不推荐)
  
-  Shell脚本文件以.sh为后缀, 但是也可以.txt等后缀 
  
-  脚本可相对路径执行, 也可绝对路径执行 
  
  
脚本编写如下:
#!/bin/bash
    echo "Hello, are u sb?"
图示如下:
 
注意:
三, shell变量
3.1 变量的一些约束和命名规则
变量名和等号之间不能有空格; 同时变量的命名有以下规则:
 - 命名只能使用英文字母, 数字和下划线, 不能以数字开头;
 - 变量中间不存在空格, 可以使用下划线;
 - 不能使用标点符号;
 - 不能使用bash中的关键字
 - 变量名一般为全大写
举个栗子:
 
[注意]
-  在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。 
  
-  变量的值如果有空格,需要使用双引号或单引号括起来。 
  
3.2 shell变量的种类
按照变量的作用域, shell变量被分为了 局部变量, 环境变量, shell变量
运行shell时,会同时存在这三种变量:
-  局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。 
-  环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。  - 自定义环境变量
  
  
- 自定义环境变量
-  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命令的结果赋给变量(重要)
两种方法
- 使用
反引号, 例如: A=`ls `
$(命令), 例如: A=$(ls)
图示如下:

 
3.4 Shell位置参数变量
[定义]
 在Linux的命令行中, 当一条命令或脚本执行时, 后面可以跟多个参数, 我们使用位置参数变量来表示这些参数;
其中, $0表示命令行本身, $1代表执行脚本时添加的第一个参数, $2代表添加的第二个参数, 以此类推.
 当参数个数超过10个时, 就要用大括号把这个数字括起来, 例如, ${10}道代表第10个参数, ${14}代表第14个参数.
图示如下:

 
在shell中可以识别的位置参数变量及含义如下表所示:
| 位置参数变量 | 作用 | 
|---|---|
| $n | n为数字, $0代表命令本身, $1-$9代表1-9个参数, 10以上的参数需要用大括号包含, 如 ${10} | 
| $* | 代表命令行中所有的参数, 把所有的参数看作是 一个整体 | 
| $@ | 代表命令行中所有的参数, 不过 $@把每个参数 区别对待 | 
| $# | 代表命令行中所有参数的个数 | 
图示如下:
 ![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4f2BHgam-1621604345465)(2021-05-20-12-31-39.png)]](https://img-blog.csdnimg.cn/20210522111251849.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25tc0xMQ1NETg==,size_16,color_FFFFFF,t_70#pic_center)
3.5 shell预定义变量
[定义]
 预定义变量是在Shell一开始时就定义的变量,这一点和默认环境变量有些类似. 不同的是, 预变量不能重新定义, 用户只能根据Shell的定义来使用这些变量;
严格来说, 位置参数变量也是预定义变量的一种, 只是位置参数变量的作用比较统一, 所以我们把位置参数变量单独划分为一类变量;
预定义变量
|预定义变量|作用|
 |$?| 表示最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。|
 |$$|当前进程的进程号(PID)|
 |$!|后台运行的最后一个进程的进程号(PID)|
图示如下:
$? 的使用

$$ 和 $!的使用

 
============================ 7.14
四, 运算符
4.1 算数运算符
[基本语法]
- 不使用expr的运算写法, " $((运算式))" 或 " $[运算式] "
- expr $m + $n 注意expr, 运算式, 运算符号之间的空格一个都不能少
- expr 加+, 减-, 乘*, 除/, 取余%
- 我们可以对比复习一下命令结果的传递, 使用反引号 `命令`, 或者是 $(命令)
- 再对比复习一下, 使用某个变量, 命令是 变 量 名 < / 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 ]
[常用判断条件]
- 两个整数之间比较
- 字符串比较 =
- 数字比较:
  
-  按照文件权限进行判断 
  
-  按照文件类型判断  
[案例实操]
-  判断test文件是否存在 
  
-  判断字符是否相同 
  
-  判断文件是否存在,是否是一个目录 
  
- 多条件判断(&& 表示前一条命令命令执行成功时,才执行后一条命令, || 表示上一条命令执行失败后, 才执行下一条命令)

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

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


6.2 case…esac语句
case…esac为多选择语句, 与其他语言中的switch…case语句类似, 是一种多分支选择结构, 每个case分支用模式)右圆括号开始, 用两个分号;;表示break, 即执行结束, 跳出整个 case…esac语句, esac(就是case反过来)作为整个case语句的结束标记;
[基本语法]
case 值 in
模式1)
    command1
    command2
    ....
;;
模式2)
    command1
    command2
    ...
;;
esac
- case 工作方式如上所示, 取值后面必须为单词in, 每一模式必须以右括号结束. case 值 in
- 取值将检测匹配的每一个模式. 一旦模式匹配, 则执行完匹配模式相应命令后不再继续其他模式. 如果无一匹配模式, 使用星号 * 捕获该值, 再执行后面的命令;
[案例实操]
- 下面的脚本提示输入 1 到 4,与每一种模式进行匹配:
  

- 下面的脚本匹配字符串:
  
 ![]](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加到10
  

-  输入1,2,3,4,5 
  
  
-  输入字符串 
  
  
$* 和 $@的辨析
先看一个借助for循环实现的栗子:
-  使用 #*作为循环的对象 
  
  
-  使用 #@作为循环的对象 
  
  
总结如下:
- #*和#@都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 $2 …$n的形式输出所有参数。
- 当它们被双引号“”包含时,“$*”会将所有的参数作为一个整体,以“$1 $2 …$n”的形式输出所有参数;“$@”会将各个参数分开,以“$1” “$2”…”$n”的形式输出所有参数。
6.4 while循环
[基本语法]
while [ 条件判断式 ]
    do
        循环程序段
    done
[案例实操]
-  从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 也不限制定义和调用的顺序,你可以将定义放在调用的前面,也可以反过来,将定义在调用的后面。
[案例实操]
-  一个简单的打印函数, 并且函数在调用时传入了参数 
  
  
-  定义一个函数,计算所有参数的和 
  
  
$@表示函数的所有参数,$?表示函数的退出状态(返回值)
 
                     
                    
                 
                    
                




 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号