shell编程规范变量详解
前言
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。
Linux 命令的执行必须依赖于 Shell 命令解释器。Shell 实际上是在 Linux 操作系统中运行的一种特殊程序,它位于操作系统内核与用户之间,负责接收用户输入的命令并进行解释, 将需要执行的操作传递给系统内核执行,Shell 在用户和内核之间充当了“翻译官”的角色。当用户登录到 Linux 系统时,会自动加载一个 Shell 程序,以便给用户提供可以输入命令的操作系统。
偷懒必备小语言
一 : shell脚本概述
1.1:shell脚本的概念
将要执行的命令按照顺序保存到一个文本文件
给该文件可执行的权限,便于运行 +一个x的执行权限
可结合各种shell控制语句以完成更复杂的操作
1.2 :shell脚本应用场景
- 重复性操作
- 批量化事务处理
- 自动化运维管理
- 服务器运行状态监控
- 定时任务执行
- ······
shell的作用-----命令解释器,“翻译官”
- 介于系统内核与用户之间,负责解释命令行
1.3:用户的登陆shell
登陆后默认使用的shell程序,一般为/bin/bash
不同shell的内部命令、运行环境等会有所区别
[root@localhost ~]# cat /etc/shells
/bin/sh
'/bin/bash'
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
1.31:type命令----显示指定命令类型
[root@shuai opt]# type cd
cd 是 shell 内嵌
[root@shuai opt]# type mkdir
mkdir 是 /usr/bin/mkdir
[root@shuai opt]# type bash
bash 是 /usr/bin/bash
[root@shuai opt]# type which
which 是 `alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde' 的别名
1.4:编写第一个shell脚本
1.41:编写脚本代码
使用vi文本编辑器
每行一条Linux命令,按执行顺序依次编写
脚本后缀为.sh
#!/bin/bash ‘shell脚本固定格式’
cd /boot ‘切换到boot目录’
pwd ‘查看当前所在位置
ls -lh vml* ’看vml开头所有文件’
~ ‘保存退出’
[root@shuai opt]# ls
first.sh rh tom.sh
1.42:赋予可执行权限
[root@shuai opt]# chmod +x tom.sh
1.5:执行脚本文件
方法一:脚本文件路径(绝对路径与相对路径)
[root@shuai opt]# ./tom.sh ‘这边必须有x权限
bash: ./tom.sh: 权限不够
[root@shuai opt]# ll
总用量 8
-rw-r--r--. 1 root root 45 7月 15 14:46 first.sh
drwxr-xr-x. 2 root root 6 10月 31 2018 rh
-rw-r--r--. 1 root root 37 7月 15 19:35 tom.sh ’没有x权限’
[root@shuai opt]# chmod +x tom.sh ‘给它加一个x权限’
[root@shuai opt]# ./tom.sh ‘执行脚本’
/boot
-rwxr-xr-x. 1 root root 6.4M 7月 7 19:06 vmlinuz-0-rescue-8a9eb400fff14ea1bad6431249fe17d2
-rwxr-xr-x. 1 root root 6.4M 11月 9 2018 vmlinuz-3.10.0-957.el7.x86_64
方法二:sh 脚本文件路径
[root@shuai opt]# sh tom.sh ‘sh不需要执行权限’
/boot
-rwxr-xr-x. 1 root root 6.4M 7月 7 19:06 vmlinuz-0-rescue-8a9eb400fff14ea1bad6431249fe17d2
-rwxr-xr-x. 1 root root 6.4M 11月 9 2018 vmlinuz-3.10.0-957.el7.x86_64
方法三:source 脚本文件路径
[root@shuai opt]# source tom.sh
/boot
-rwxr-xr-x. 1 root root 6.4M 7月 7 19:06 vmlinuz-0-rescue-8a9eb400fff14ea1bad6431249fe17d2
-rwxr-xr-x. 1 root root 6.4M 11月 9 2018 vmlinuz-3.10.0-957.el7.x86_64
[root@shuai boot]# ‘你会细心的发现source环境发生变化’
方法四:点后面加空格 脚本文件路径
[root@shuai boot]# . tom.sh
/boot
-rwxr-xr-x. 1 root root 6.4M 7月 7 19:06 vmlinuz-0-rescue-8a9eb400fff14ea1bad6431249fe17d2
-rwxr-xr-x. 1 root root 6.4M 11月 9 2018 vmlinuz-3.10.0-957.el7.x86_64
[root@shuai boot]# ‘点跟source作用一样’
方法总结
./:必须要有x执行权限
sh执行命令不需要
.空格跟source执行会切换路径
1.6:更完善的脚本结构
脚本声明
注释信息
可执行语句
用刚刚编辑的示例
#!/bin/bash
cd /boot
echo "所在的路径位置" '输出好友信息'
pwd
echo "查看所有vml开头的文件信息" '输出好友信息'
ls -lh vml*
~ 'wq保存退出'
echo代表输出语句,输出子串字符双引号
[root@shuai opt]# sh tom.sh
所在的路径位置
/boot
查看所有vml开头的文件信息
-rwxr-xr-x. 1 root root 6.4M 7月 7 19:06 vmlinuz-0-rescue-8a9eb400fff14ea1bad6431249fe17d2
-rwxr-xr-x. 1 root root 6.4M 11月 9 2018 vmlinuz-3.10.0-957.el7.x86_64
二:重定向与管道操作
2.1:交互式硬件设备 0 1 2
标准输入:从该设备接受用户输入的数据
标准输出:通过该设备向用户输出数据
标准错误:通过该设备报告执行出错信息
类型 | 设备文件 | 文件描述 | 默认设备 |
---|---|---|---|
标准输入 | /dev/stdin | 0 | 键盘 |
标准输出 | /dev/stdout | 1 | 显示器 |
标准错误输出 | /dev/stder | 2 | 显示器 |
2.2:重定向操作
类型 | 操作符 | 用途 |
---|---|---|
重定向输入 | < | 从指定的文件读取数据,而不是从键盘输入 |
重定向输出 | > | 将输出结果保存到指定的文件(覆盖原有内容) |
重定向输出 | >> | 将输出结果追加到指定的文件 |
标准错误输出 | 2> | 将错误信息保存到指定的文件(覆盖原有内容) |
标准错误输出 | 2>> | 将错误信息追加到指定的文件中 |
混合输出 | &> | 将标准输出,标准错误的内容保存到同一个文件中 |
[root@shuai opt]# ls
first.sh rh tom.sh
[root@shuai opt]# cat 2.txt 2> shuai.txt '标准输错方式' 不报错
[root@shuai opt]# vim shuai.txt
cat: 2.txt: 没有那个文件或目录
[root@shuai opt]# cat 2.txt > shuai02.txt '把2去掉就是正常输出'
cat: 2.txt: 没有那个文件或目录
[root@shuai opt]# grep "bash$" /etc/passwd &>hua.txt
[root@shuai opt]# cat hua.txt
root:x:0:0:root:/root:/bin/bash
liu:x:1000:1000:liu:/home/liu:/bin/bash
[root@shuai opt]# grep "lisi$" /etc/passwd &>hu02a.txt '标准错误输出'
[root@shuai opt]# cat hu02a.txt
[root@shuai opt]# cat ab.txt &> hu02a.txt
[root@shuai opt]# cat hu02a.txt
cat: ab.txt: 没有那个文件或目录
###不提示下载 null黑洞不同于回收站 所有信息都消失
[root@shuai opt]# yum -y install httpd &> /dev/null
[root@shuai opt]# rpm -q httpd
httpd-2.4.6-93.el7.centos.x86_64 '已下载好 就是信息不提示'
2.3:管道操作符号“|”
将左侧的命令输出结果,作为右侧命令的处理对象
[root@shuai opt]# grep "bash$" /etc/passwd '查看以bash结尾的登录账号'
root:x:0:0:root:/root:/bin/bash
liu:x:1000:1000:liu:/home/liu:/bin/bash
###以冒号分隔,输出第1,7个字段 ##如果不写-F 就是指标符号跟空格
[root@shuai opt]# grep "bash$" /etc/passwd | awk -F: '{print $1,$7}'
root /bin/bash
liu /bin/bash
awk是正则表达式的一种
大部分情况下
grep:过滤关键字 grep egrep
sed 老二 按行读取
awk 老三 按列读取数据
sed: 按行读取
awk:按列读取数据
$1,$7:位置变量
[root@shuai opt]# df -Th
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root xfs 50G 5.0G 46G 10% /
devtmpfs devtmpfs 3.6G 0 3.6G 0% /dev
tmpfs tmpfs 3.6G 0 3.6G 0% /dev/shm
tmpfs tmpfs 3.6G 13M 3.6G 1% /run
tmpfs tmpfs 3.6G 0 3.6G 0% /sys/fs/cgroup
/dev/sda1 xfs 1014M 179M 836M 18% /boot
/dev/mapper/centos-home xfs 242G 33M 242G 1% /home
tmpfs tmpfs 726M 4.0K 726M 1% /run/user/42
tmpfs tmpfs 726M 48K 726M 1% /run/user/0
/dev/sr0 iso9660 4.3G 4.3G 0 100% /run/media/root/CentOS 7 x86_64
####提取第一个跟第六个
[root@shuai opt]# df -Th | awk '{print $1,$6}'
文件系统 已用%
/dev/mapper/centos-root 10%
devtmpfs 0%
tmpfs 0%
tmpfs 1%
tmpfs 0%
/dev/sda1 18%
/dev/mapper/centos-home 1%
tmpfs 1%
tmpfs 1%
/dev/sr0 100%
##过滤以/结尾 第一列跟第六列
[root@shuai opt]# df -Th | grep "/$" | awk '{print $1,$6}'
/dev/mapper/centos-root 10%
三:shell脚本变量详解
3.1 :变量的作用、类型
变量:变量是编程中最常见的一种临时在内存中存取数据的一种方式
3.11:变量的作用
为灵活管理limux系统提供特定参数,有两层意思
变量名:使用固定的名称,由系统预设或用户定义
变量值:能够根据用户设置、系统环境的变化而变化
3.12:变量的类型
自定义变量:由用户自己定义、修改和使用
环境变量:由系统维护,用于设置工作环境
位置变量:通过命令行给脚本程序传递参数
预定义变量:Bash中内置的一类变量,不能直接修改
3.2:自定义变量
3.21:定义一个新的变量与查看变量的值
定义一个新的变量——自定义变量 = echo
变量名以字幕或下划线开头,区分大小写,建议全大写
变量格式 变量名=变量值
查看变量的值
echo $变量名
3.22:变量命名规则
命名只能使用英文字母,数字和下划线,首个字符不能用数字开头’
中间不能有空格,可以用下挂线—
不能使用标点符号
不能使用bash的关键字【可用help命令查看保留关键字】
VFDA=2
age=90 整型 ##这边的=叫赋值符号
name=‘baisn’ 字符串
score=88.8 【单精浮点 4 字节】shuai=8.88【双精 浮点 8字节】
shuai=20
[root@shuai opt]# echo $shuai
20
[root@shuai opt]# name=shuaige
[root@shuai opt]# echo $name
shuaige
[root@shuai opt]# echo $name shuai
shuaige shuai
3.23:取消变量unset
[root@shuai opt]# shuaige=wo
[root@shuai opt]# echo $shuaige
wo
[root@shuai opt]# echo $shuaige
##已经取消
3.24:赋值时使用引号
双引号:允许通过符号引用其他变量值,即在可以代表字符串的情况下,若是有 符号引用其他变量值,即在可以代表字符串的情况下,若是有符号引用其他变量值,即在可以代表字符串的情况下,若是有存在也可以代表标量
单引号:禁止引用其他变量值,是为普通字符,即视为字符串,不识别变量符号反撇号:命令替换,提取命令执行后的输出结果变量=反撇号相当于变量=是为普通字符,即视为字符串,不识别变量符号反撇号:命令替换,提取命令执行后的输出结果变量=反撇号相当于变量=()
[root@shuai opt]# text=20
[root@shuai opt]# echo $text
20
[root@shuai opt]# text2="tom $text"
[root@shuai opt]# echo $text2
tom 20
[root@shuai opt]# text2='tom $text'
[root@shuai opt]# echo $text2
tom $text
#
[root@shuai ~]# ps aux | wc -l
249
[root@shuai ~]# shuai=`ps aux | wc -l` `命令`或者 $(命令)
[root@shuai ~]# echo $shuai
250
[root@shuai ~]# mei=$(ps aux | wc -l)
[root@shuai ~]# echo $mei
250
3.25:从键盘输入内容为变量赋值 read
read [-p 提示信息]变量名
[root@shuai opt]# read -p "你今年多大了?: " xiaoge
你今年多大了?: 21
[root@shuai opt]# echo $xiaoge
21
[root@shuai opt]# vim shuai.txt
#!/bin/bash
#this is my age
read -p "请输入你的年龄: " xiaoge
echo "你的年龄是:$xiaoge"
:wq保存退出
[root@shuai opt]# sh shuai.txt
请输入你的年龄: 21
你的年龄是:21
3.26:设置变量的作用范围 export 设置全局可用
格式1:export 变量名
格式2:export 变量名=变量值
两种格式可以混合使用
export可以把变量定义为全局变量,这样的话,不管是切换bash环境,还是切换用户都可以使用该变量
格式一:export 变量名...
格式二:export 变量名=变量值...
两种格式可以混合使用
实例:
[root@shuai opt]# shuai=55
[root@shuai opt]# echo $shuai
55
[root@shuai opt]# bash '设置bash环境变量'
[root@shuai opt]# echo $shuai
'已经显示不出来了'
[root@shuai opt]# exit '退出bash环境'
exit
[root@shuai opt]# echo $shuai
55
[root@shuai opt]# export shuai '导出为全局变量'
[root@shuai opt]# bash
[root@shuai opt]# echo $shuai '引用全局变量'
55
3.27: 整数变量的运算 expr
expr 变量1 运算符 变量2 [运算符 变量3].。。。。。
常用运算符
- 加法运算:+
- 减法运算:-
- 乘法运算:* 乘法必须要加\,因为在shell语言中,*代表通配符号
- 除法运算:/
- 求模(取余)运算:%
[root@shuai opt]# expr 1 + 2
3
[root@shuai opt]# expr 2 - 1
1
[root@shuai opt]# expr 5 / 2
2
[root@shuai opt]# expr 3 / 10
0
[root@shuai opt]# expr 3 \* 3
9
[root@shuai opt]# expr 22 % 10
2
#!/bin/bash
read -p "输入第一天跑步用了多少小时" text1
read -p "输入第二天跑步用了多少小时" text2
#进行运算一下
text=`expr $text1 + $text2`
echo "两天跑步总用时为$text"
输入第一天跑步用了多少小时5
输入第二天跑步用了多少小时5
两天跑步总用时为10
四:特殊的shell变量
4.1 环境变量
由系统提前创建,用来设置用户的工作环境
配置文件: /etc/profile、~/.bash_prolile
4.2 常见的环境变量
PWD\、PATH
USER、SHELL、HOME
[root@shuai ~]# echo $PATH '命令环境变量'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@shuai ~]# echo $PWD '当前所在位置'
/root
[root@shuai ~]# vim tom.sh
#!/bin/bash
#进行减法运算
echo "第一个位置变量数值$1
echo "第二个位置变量数值$2
lisi=`expr $1 - $2`
echo "余数为$lisi"
[root@shuai ~]# sh tom.sh 66 22
第一个位置变量数值66
echo 第二个位置变量数值22
余数为44
[root@shuai ~]# vim tom.sh
#!/bin/bash
#进行减法运算
echo "第一个位置变量数值$1
echo "第二个位置变量数值$2
lisi=`expr $1 - $2`
echo "余数为$lisi"
echo "继续努力$0"
[root@shuai ~]# sh tom.sh 66 22
第一个位置变量数值66
echo 第二个位置变量数值22
余数为44
继续努力tom.sh
4.3:预定义变量
$#:命令行中位置变量的个数
$*:所有位置变量的内容
$?:上一条命令执行后返回的状态,当返回状态值为0时表示正常,非0值表示执行异常或出错
$0:当前执行的进程/程序名
分析脚本
[root@localhost opt]# vim ddd.sh
#!/bin/bash
TARFILE=beifen-`date +%s`.tgz '设置变量名称,+%s表示从1970至今经过的秒数,所以文件名不会出现重复的情况,就不会有被覆盖的风险'
tar zcvf $TARFILE $* &> /dev/null 'tar工具压缩输出到 /dev/null'
echo "已执行$0个脚本" '当前执行的进程名'
echo "共完成$#个对象的备份" '位置变量的个数'
echo "具体内容包括:$*" '所有位置变量的内容'
~
[root@localhost opt]# ./ddd.sh /etc/passwd /etc/shadow
已执行./ddd.sh个脚本
共完成2个对象的备份
具体内容包括:/etc/passwd /etc/shadow
'/dev/null:黑洞,数据到这里就消失了,无法找回'
[root@shuai ~]# vim tom.sh
#!/bin/bash
#进行减法运算
echo "第一个位置变量数值$1
echo "第二个位置变量数值$2
lisi=`expr $1 - $2`
echo "余数为$lisi"
echo "继续努力$0"
echo "详细数字$*"
echo "数字的个数$#"
~
[root@shuai ~]# sh tom.sh 66 22
第一个位置变量数值66
echo 第二个位置变量数值22
余数为44
继续努力tom.sh
详细数字66 22
数字的个数2
%Y表示年
%m表示月
%d表示日
%H表示小时
%M表示分钟
%S表示秒
%s表示从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数,相当于time函数
%w表示一周中的第几天。
[root@shuai opt]# date '显示时间'
2020年 07月 16日 星期四 11:48:57 CST
[root@shuai opt]# date +%F '显示当前时间'
2020-07-16
[root@shuai opt]# date +%Y%M%D '显示年月日'
20204907/16/20
[root@shuai opt]# date "+现在时间是:%Y-%m-%d %H-%M-%S"
现在时间是:2020-07-16 11-51-39
[root@shuai ~]# date +%s '从1970年1月1日到现在的秒数'
1594867760
您学废了吗