一、 shell脚本
1.1 shell脚本的概述
- 将要执行的命令按顺序保存到一个文本文件
- 给该文件可执行权限
- 课结合各种shell控制语句以完成更复杂的操作
shell是一个面向字符串的编程语言,介于系统内核与用户之间,负责解释命令行,可用跟Python之类的其他语言配合起来,比如某个复杂的功能使用一个Python脚本来实现,然后再shell中调用这个脚本实现比较复杂的功能,或者反过来,再Python脚本中调用外部的shell脚本来提高自动化的效率。
-
shell可针对Linux系统做自动化运维和状态监控
-
python可针对通过API接口对应用程序做数据的收集、统计和分析
shell脚本的应用场景
- 重复性操作
- 交互性任务
- 批量事务处理
- 服务运行状态监控
- 定时任务执行
1.2 shell脚本的作用
shell脚本的作用
- 自动化运维
- 批量化重复操作可用编写脚本结合计划自动周期运行
- 减轻管理员工作量
- 提高处理文本文件的速度
- 避免配置出错
1.3 .shell脚本的类型
我们可用使用vim /etc/shells命令查看shell脚本的类型:
我们平时最常使用的就是bash、tcsh、csh、nologin这些shell,以下是这些shell的种类与功能
| 种类 | 功能 |
|---|---|
| bash | 基准于GNU的框架下发展出的shell |
| csh | 语法有点类似于C语言的shell |
| tcsh | 整合了csh,提供更多的功能 |
| sh | 已经被bash所替换 |
| nologin | 这个shell可用让用户无法登陆主机 |
PS:bash(/bin/bash)是目前大多数Linux版本采用的默认shell
1.4 shell脚本的构成与编程规范
- 脚本申明(解释器),若第一行为"#!/bin/bash",表示此行以下的代码语句是通过/bin/bash程序来解释执行,#!/bin/bash为默认解释器。还有其他类型的解释器,比如#!/usr/bin/python、#!/usr/bin/expect。
- 注释信息:以"#"开头的语句表示为注释信息,被注释的语句再运行脚本时不会被执行。
- 可执行语句,比如echo命令,用于输出“ ”之间的字符串
PS:shell 脚本代码 申明解释器 #!/bin/bash 或省略
python 脚本代码 必须申明解释器#!/usr/bin/pyhton或#!+python执行文件的其他路径
举例:我们创建一个基本的shell脚本格式
#!/bin/bash #申明解释器
#desc:first shell script <User 2008-08-08> #做脚本的注释信息
echo "hello world" #代码块
我们接下来需要执行这个shell脚本,那我们需要赋予这个文件执行的权限
运行脚本的方法除了上图可以使用绝对路径或相对路径指定脚本的路径运行外还有以下几种方式:
-
指定shell程序来直接解释运行脚本
./demo.sh #使用相对路径命令执行脚本文件(当前文件夹下的脚本文件执行) /User/demo.sh #使用绝对路径命令执行脚本文件(在根目录下的User目录中执行脚本文件) bash demo.sh #使用shell程序直接解释运行脚本 sh demo.sh #使用shell程序直接解释运行脚本
-
会在当前shell环境中执行脚本里的代码操作,但是脚本文件中的代码或者命令可能会影响当前shell环境
source demo.sh #在当前shell环境中执行脚本 . demo.sh #在当前shell环境中执行脚本
我们重新创建一个简单的shell脚本举例对比运行脚本命令的区别:
脚本内容如下图所示
运行方式①:
运行方式②:
二、重定向与管道操作
2.1 管道操作 “|”
将管道符号“|”左侧的命令输出的结果,作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道符
举例:
ps aux | wc -l #统计当前系统中的进程数(实际数量-1为进程数)
echo “123321” | passwd --stdin user1 #给user1用户设置“123321”的用户密码
pgrep -u u01 | xargs kill -9 #查询用户u01正在使用的进程的inode号,并将该用户使用的进程杀死
补充:使用xargs的情况说明右边的命令一定要跟对象才能执行,才需要使用xargs命令来传递参数
编程语言分为强类型与弱类型两种
强类型语言在进行变量时需要定义数据类型(比如C、C++、JAVA、GO)
弱类型语言进行变量时不需要定义数据类型(比如shell、python)
2.2 交互式硬件设备
- 标准输入:从该设备接收用户输入的数据
- 标准输出:通过该设备想用户输入数据
- 标准错误:通过该设备报告执行出错信息
| 类型 | 设备文件 | 文件描述编号 | 默认设备 |
|---|---|---|---|
| 标准输入 | /dev/stdin | 0 | 键盘 |
| 标准输出 | /dev/stdout | 1 | 显示器 |
| 标准错误输出 | /dev/stderr | 2 | 显示器 |
2.3 重定向操作
| 类型 | 操作符 | 用途 |
|---|---|---|
| 重定向输入 | < | 从指定的文件读取数据,而不是从键盘输入 |
| 重定向输出 | > | 将输出结果保存到指定的文件(覆盖原有内容) |
| 重定向追加 | >> | 将输出结果追加到指定的文件尾部 |
| 重定向错误输出 | 2> | 将错误信息保存到指定的文件(覆盖原有内容) |
| 重定向错误追加 | 2>> | 将错误信息追加到指定的文件中 |
| 混合输出 | &> | 将标准输出、标准错误的内容保存到同一个文件中 |
| 混合追加 | &>> | 将标准输出、标准错误的内容追加到同一个文件中 |
PS:重定向输入要关闭SELinux即setenforce 0操作
2>&1 代表错误输出被重定向到标准输出当中,而标准输出会重定向到文件中,因此错误输出也重定向到文件中
举例: 重定向输入:
重定向输出与追加:
重定向错误输出与追加:
混合输入与追加:
2&>1:
三、自定义变量
3.1如何定义变量
方法一:直接进行定义
格式:变量名=变量值
变量名一定要以字母或者下划线开头,区分大小写,建议全大写
变量如何带有空格定义:
举例:NAME='zhang san' #定义变量的变量值两边加上单引号或双引号才能生效
NAME=zhang san #不加引号,系统中会单独识别NAME=zhang这个变量定义,空格后的san将无法识别,导致定义失败
单引号双引号的使用区别:
echo '$NAME' #此命令含义为将$NAME这串字符输出到屏幕上
$name
echo "$NAME" #此命令含义为将"$NAME"这个name的变量名的变量值输出到屏幕上
zhang san
方法二:使用read命令
使用read命令可以获取标准输入的内容给变量,read命令有以下几种表现方式:
- read [变量名]
- read -p [变量名]
方法三:使用shell脚本实现
配置上图完成后,我们验证一下结果:
3.2 变量作用的范围
默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再使用。
可以通过内部命令export将指定的变量为全局变量(即环境变量),使用户定义的变量在所有子shell环境中可以继续使用。
格式有如下两种:
- export [变量名]
- export [变量名]=[变量值]
局部变量举例:
我们先定义一个变量:
然后使用pstree命令查看我们现在所处的子shell环境: