目录
前言
本篇是对shell脚本编程规范和变量的复习,重点部分详细写了一下,其他部分移步至我对应的博客
一、shell编程规范
1.1 shell的作用
命令解释器,翻译官,介于用户和内核之间,复制解释命令行
计算机用户输入相关指令,shell进行解释,转换成计算机可以识别的二进制语言,传递给内核,内核调用系统资源执行,并输出相应的结果
1.2 查看shell环境
[root@localhost~]# cat /etc/shells
/bin/sh #以前的shell环境
/bin/bash #替代了sh,默认环境
/sbin/nologin #用户无法登录
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh #csh的增强版
/bin/csh #类似c的shell环境
用户登录时,会指定shell环境
1.3 为什么要学shell
- 完成自动化运维
- 批量化的重复操作
- 结合crontab完成周期性任务
- 可以帮运维人员减轻工作量
- 提高正确率,脚本的执行结果始终一样
shell是一种弱类型语言,定义变量时,定义变量时不需要事先定义数据类型 (Python也是)解释性语言
强类型语言: Java c c++ go 定义变量时需要事先定义他的数据类型( 整数型、浮点型、字符型......)
1.4 shell脚本构成
1.申明解释器
#!/bin/bash (默认解释器) #!/usr/bin/python
#作者,创作日期,脚本的功能,维护信息等
2.注释信息 #开头,被注释的语句在脚本运行时,不被执行
3.执行的语句
vim first.sh
#写入以下脚本代码
#!/bin/bash
#my first shell script <stevelu 2022-4-7>
cd /boot
echo "当前的目录位于"
pwd
echo "其中以vml开头的文件包括:"
ls -lh vml*
1.5 执行脚本的方法
1.路径+脚本名,需要权限
chmod +x first.sh
- 绝对路径
- 相对路径
2.调用解释器 不需要权限
- bash 脚本名
- source或 . 不建议使用,可能 会影响系统环境
3.写入PATH环境,需要权限
- 将文件放入已有的PATH环境目录中
- 将脚本所在目录加入PATH环境
注:
source 和 . 会在当前 shell 环境中执行脚本
bash、sh、绝对路径、相对路径执行的脚本,会创建一个子shell环境,并在这个子shell环境中执行这个脚本
[root@localhost/data/sh]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
#/usr/local/sbin:管理员才能执行的自己创建的命令或者第三方的命令
#/usr/local/bin:所有用户可以执行的自己创建的命令或者第三方的命令
#/usr/sbin:管理员才能执行的系统命令
#/usr/bin:所有用户可以执行的系统命令
#/root/bin:默认不存在
[root@localhost/data/sh]# vim /etc/profile
export PATH=$PATH:/data/sh
[root@localhost/data/sh]# source /etc/profile
#刷新
[root@localhost/data/sh]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/data/sh
[root@localhost/data/sh]#
1.6 重定向和管道操作
1.6.1 交互式硬件设备
- 标准输入:从该设备接收用户输入的数据
- 标准输出:通过该设备向用户输出数据
- 标准错误:通过该设备报告执行出错信息
类型 |
设备文件 |
文件描述编号 |
默认设备 |
标准输入 |
/dev/stdin |
0 |
键盘 |
标准输出 |
/dev/stdout |
1 |
显示器 |
标准错误输出 |
/dev/stderr |
2 |
显示器 |
1.6.2 重定向操作
类型 |
操作符 |
用途 |
重定向输入 |
< |
从指定文件读取数据,而不是从键盘输入 |
重定向输出 |
> |
将输出结果保存到指定的文件(覆盖原有内容) |
重定向输出 |
>> |
将输出结果追加到指定的文件尾部 |
重定向错误输出 |
2> |
将错误信息保存到指定的文件(覆盖原有的内容) |
重定向错误输出 |
2>> |
将错误信息追加到执行的文件中 |
混合输出 |
&> |
将标准输出、标准错误的内容保存到同一个文件中 |
#两种混合输出方式,老程序员喜欢用第二种
ls-lh &> log.txt
ls -lh >log.txt 2>&1
ls -lh 标准输出 1--->屏幕
>log.txt 1-->log.txt 重定向至屏幕
2>&1 2-->1 1指向log.txt,所以2也就指向log.txt
二、shell变量
2.1 变量的作用
用来存放系统和用户需要使用的特定参数(值)
- 变量名:使用固定的名称,由系统预设或用户定义
- 变量值:能够根据用户设置、系统环境的变化而变化
2.2 变量的类型
- 自定义类型:由用户自己定义、修改和使用
- 特殊变量:环境变量,只读变量,位置变量,预定义变量
2.2.1 自定义变量
1.变量名以字母或下划线开头,区分大小写,建议全大写 变量名=变量值
2.查看变量的值 echo $变量名
3.赋值时使用引号:
- 双引号:允许通过$符号引用其他变量值
- 单引号:禁止引用其他变量值,$视为普通字符
- 反撇号:命令替换,提取命令执行后的输出结果
4.从键盘输入内容为变量赋值 read [ -p " 提示信息 " ] 变量名
造成上述情况的原因是运行的bash环境的差异,下面就详细补充一下
子bash进程中的变量在父bash进程中无法查看(全局变量的补充)
#实验前的name没有值,以及进程树所在地
[root@localhost~]# echo $name
[root@localhost~]# pstree
─sshd───sshd───bash───pstree
那么如何使该变量无论在哪个bash环境中都生效呢?我们需要将变量写入系统的文件中
[root@localhost~]# source /etc/profile
#加载一下
得出结论,命令行的全局变量只对后面的bash环境有效,且在一个进程树下,要想所有bash环境生效,写入系统文件中
系统环境文件
/etc/profile
/etc/bashrc
~/.bash_profile
~/.bashrc
env命令显示所有环境变量
- 系统每次启动都会自动执行 /etc/profile 文件里的命令,这个文件是对全局有效的(所有的shell环境和用户,是当之无愧的老大)
- 不同用户登录系统 会自动执行 自己家目录中的 ~/.bash_profile 文件中的命令,自动执行 ~/.bashrc
- ~/.bashrc 当前用户每切换一个shell环境都会自动执行,执行 /etc/bashrc
- /etc/bashrc 针对所有用户的,用户每切换一个shell环境都会自动执行
变量替换
tmp=$a
a=$b
b=$tmp
# ab之间的数值进行替换,借助第三个变量来实现
2.2.2 位置变量
$0 代表脚本本身
$# 代表脚本后面跟的参数(位置变量)的个数
$* 不加双引号的话 $*和$@都代表脚本后面跟的所有参数,加上双引号 "$*" 会把所有参数当做一个整体的参数(此时参数数量为1)去看待
$@ 加上双引号 "$@" 会把脚本后面跟的每一个参数当做一个个体去看待
$? 代表上一条命令或者脚本执行后返回的状态码,返回值为0表示执行正确,为非0值表示执行异常
return 退出函数时获取的返回值(0-255,超过部分 %256 取余)
shell变量详细解析的博客:
https://blog.csdn.net/qq_42327944/article/details/123832407?spm=1001.2014.3001.5502
三、运算
3.1 整数运算
shell默认只支持整数的运算。常用的运算表达式如下
i=$(expr 12 \* 5)
i=$((12*5))
i=$[12*5]
let i=12*5
let i++ 等价于 i=$[$i+1]
let i-- 等价于 i=$[$i-1]
let i+=2 等价于 i=$[$i+2]
let i/=2 等价于 i=$[$i/2]
3.2 浮点数运算
- echo "字符串" |bc
- awk 'BEGIN {print 浮点运算字符串}'
shell中的运算详细解析:
https://blog.csdn.net/qq_42327944/article/details/123836316?spm=1001.2014.3001.5502
总结
定义变量的方法1:
变量名=变量值
定义变量的方法2:
read [ -p "请输入"]变量名 从键盘输入中获取变量名的值
echo -n "请输入"
read name
四种运算
i=$((10*20 ))
i=$[10*20]
let i=10*20
expr 10\*20