Shell编程规范与变量
文章目录
前言
在一些复杂的Linux维护工作中,大量重复性的输入和交互操作不但费时费力,而且容易出错。
而编写一个恰到好处的shell脚本程序,可以批量处理,自动化的完成一系列维护任务,大大减轻管理员的负担。
一、Shell概述
1.什么是Shell脚本
简单来说,只要将平时的各种Linux命令按顺序保存到一个文本文件中,然后添加可执行权限,这个文件就成为一个Shell脚本了,就是复杂问题简单化。
2.Shell脚本应用场景
重复性操作
交互性任务
批量事务处理
服务运行状态监控
定时任务执行
…
3.Shell脚本的作用
介于系统内核(操作系统)与用户(应用层)之间,复制解释命令行,俗称命令解释器,“翻译官”
用户写的命令通过Shell翻译成二进制,才可以被内核识别,去控制硬件
2.1 过程图
4.用户的登录Shell
登录后默认使用的Shell程序,一般为/bin/bash种类
不用的Shell的内部命令,运行环境等会有所区别
示例:
5.Linux常用的Shell种类
不同的shell具备不同的功能,shell还决定了Linux中默认的shell是/bin/ bash,流行的shell有ash、bash、ksh、csh, zsh等,不同的shell 都有自己的特点以及用途。
bash
大多数Linux系统默认使用的shell , bash shell是Bourne shell 的一个免费版本,它是最 早的Unix. shell, bash还有一个特点,可以通过help命令来查看帮助。包含的功能几乎可以涵盖shell所具有的功能,所以一般的shell脚本都会指定它为执行路径。
csh
C shell 使用的是“类C”语法,csh是具有C语言风格的一种shell, 其内部命令有52个,较为庞大。目前使用的并不已经被/bin/tcsh所取代。
ksh
Korn shell 的语法与Bourne shell相同,同时具备了C shell的易用特点。许多安装脚本都使用ksh, ksh有42条内部命令,与bash相比有一定的 限制性。
tcsh
tcsh是csh的增强版,与C shell完全兼容。
sh
是一个快捷方式,已经被/bin/bash所取代。
nologin
指用户不可登录
二、编写Shell脚本格式
1.编写脚本代码
要求:
使用vim或vi文本编辑器
每行一条Linux命令,按执行顺序依次编写
格式:
#!/bin/bash #用/bin/bash来解释Shell命令(先定义shell脚本种类)
#查询/boot目录下的所有的子文件和子目录 (对你脚本实现要求的描述)
shell脚本命令
cd /boot
pwd
ls -lh vml*
2.赋予可执行权限
使脚本具有执行权限
[aaa@qq.com ~]# chmod +x first.sh
3.执行脚本文件
- ./ 脚本文件路径(绝对路径与相对路径)必须要赋予x全选
[aaa@qq.com ~]# ./first.sh #需要权限才可以执行输出
[aaa@qq.com ~]# chmod +x first.sh #添加x权限
[aaa@qq.com ~]# ./first.sh
- sh 脚本文件路径
[aaa@qq.com ~]# sh first.sh #不需要权限,也可以操作
[aaa@qq.com ~]# pwd #仍在起始环境,目录位置不变
- source 脚本文件路径,也可以通过 “ . ” 来执行
[aaa@qq.com ~]# chmod -x first.sh
[aaa@qq.com ~]# source first.sh #不需要执行权限就可以操作,立马让工作环境生效
[aaa@qq.com boot]# pwd #会自动切入脚本中的环境,目录位置改变
完整示例
脚本声明
注释信息
可执行语句
[aaa@qq.com ~]# vim first.sh
[aaa@qq.com ~]# chmod +x first.sh
[aaa@qq.com ~]# ./first.sh
#!/bin/bash
#查询/boot目录下所有的子文件和子目录
cd /boot
echo "当前位于:" 输出友好提示信息
pwd
echo “显示当前路径下以vml为开头的文件或目录:”
ls -lh vml*
三、重定向
1.什么是重定向
在实际的Linux系统维护中,可以改变输入、输出内容的方向,而不使用默认的标准输入、输出设备(键盘和显示器),这种操作称为重定向。(改变输入来源,输出目标)
2.交互式硬件设备
标准输入:从该设备接收用户输入的数据
标准输出:通过该设备向用户输出数据
标准错误:通过该设备报告执行出错信息
3.重定向分类
补充:
read
格式:read (选项) (参数)
选项:
-p:指定读取值时候的提示符
-t: 指定读取值时候等待的时间(秒)
-a array :指定输入一个数组,赋值给array
-n 2 :指定输入字符的任意类型的个数为2
示例:
1.从键盘输入的例子
2.
[aaa@qq.com ~]# read -p "输入a变量的变量值:" a
输入a变量的变量值:112233aabb
[aaa@qq.com ~]# echo $a
112233aabb
3.密码交互(重定向输入)
一步操作完成用户的密码设置
[aaa@qq.com ~]# vi pass.txt
[aaa@qq.com ~]# useradd yangyang
[aaa@qq.com ~]# passwd --stdin yangyang < pass.txt
4.重定向输出
[aaa@qq.com ~]# uname -p
x86_64
[aaa@qq.com ~]# uname -p > kernel.txt 覆盖文件
[aaa@qq.com ~]# cat kernel.txt
x86_64
[aaa@qq.com ~]# uname -p > kernel.txt
[aaa@qq.com ~]# cat kernel.txt
x86_64
[aaa@qq.com ~]# uname -p >> kernel.txt 追加
[aaa@qq.com ~]# cat kernel.txt
x86_64
x86_64
[aaa@qq.com ~]# uname -r >> kernel.txt
[aaa@qq.com ~]# cat kernel.txt
x86_64
x86_64
3.10.0-693.el7.x86_64 查看操作系统的内核版本
4.错误输出
[aaa@qq.com ~]# ./first.sh
[aaa@qq.com ~]# ./first.sh 2> error.txt
[aaa@qq.com ~]# cat error.txt 无信息,原因只有是错误的信息才会显示
5.错误重定向,(错误信息不可见,都存在指定文件中)
[aaa@qq.com ~]# vim http.sh
[aaa@qq.com ~]# chmod +x http.sh
[aaa@qq.com ~]# ./http.sh
[aaa@qq.com ~]# cd /opt/
[aaa@qq.com opt]# ls -lh
[aaa@qq.com opt]# cat cd_err.txt
[aaa@qq.com opt]# cat con_err.txt
[aaa@qq.com opt]# cat make_err.txt
[aaa@qq.com opt]# cat makeinsatll_err.txt
[aaa@qq.com opt]# cat rh
#!/bin/bash
#apache server install
cd /usr/local/httpd-2.4.25/ &> /opt/cd_err.txt
./configure &> /opt/con_err.txt
make &> /opt/make_err.txt
make install &> /opt/makeinsatll_err.txt
四、管道操作
1.什么是管道操作
管道操作符号“ | ”,简单来说就是一条命令实现多条命令结果
将左侧的命令输出结果,作为右侧命令的处理对象
cmd1 | cmd2 […| cmdn]
示例:
[aaa@qq.com ~]# ls -lh /boot/ | grep "vml"
[aaa@qq.com ~]# df -Th | grep "/$" (以“/”为结尾的文件)
[aaa@qq.com ~]# df -Th | grep "/$" | awk '{ print $6 }' (查看以“/”为结尾的文件,并输出第六个文件)
五、Shell变量
1.变量的作用
用来存放系统和用户需要使用的特定参数(值)
变量名:使用固定的名称。 由系统预设或用户定义
变量值:能够根据用户设置。 系统环境的变化而变化
2.变量的类型
自定义变量:由用户自已定义。 修改和使用
特定变量: 环境变量 , 只读变量 ,位置变量 , 预定义变量
2.1 自定义变量
定义一个新的变量
要求:变量名以字母或下划线开头、区分大小写,建议全大写
格式:变量名=变量值(“=”左边为变量名,右边为变量值)
3. 查看(取)变量的值
格式:echo $变量名
示例:
[aaa@qq.com~]# ProductaPython
[aaa@qq.com~]# Version=2.7.13
[aaa@qq.com~]# echo $Product
Python
[aaa@qq.com~]# echo $Product $Version
Python 2.7.13
[aaa@qq.com ~]# A=cc
[aaa@qq.com ~]# echo $A
cc
[aaa@qq.com ~]# AB=ccdd
[aaa@qq.com ~]# echo $A $AB
cc ccdd
4.赋值时使用引号
双引号:允许通过
符
号
引
用
其
他
变
量
值
单
引
号
:
禁
止
引
用
其
他
变
量
值
,
符号引用其他变量值 单引号:禁止引用其他变量值,
符号引用其他变量值单引号:禁止引用其他变量值,示为普通字符
反撇号:命令替换。提取命令执行后的输出结果
4.1 从键盘输入内容为变量赋值
read [-p "提示信息"] 变量名
示例:
[aaa@qq.com ~]# $PATH
-bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin: 没有那个文件或目录
[aaa@qq.com ~]# Z='$PATH'
[aaa@qq.com ~]# echo $Z
$PATH
[aaa@qq.com ~]# Z="$PATH"
[aaa@qq.com ~]# echo $Z
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[aaa@qq.com ~]# B=`ls -lh /root`
[aaa@qq.com ~]# echo $B
5.设置变量的作用范围
变量分为:局部、全局
格式1:export 变量名 ... #两种格式可以混合使用
格式2:export 变量名=变量值 ...
变量名=变量值 … 局部(在当前的bash可用,切换到其它bash不可用)
示例:
[aaa@qq.com ~]# echo "$Product $Version"
Benet 6.0
[aaa@qq.com ~]# export Product Version #导出为全局变量
[aaa@qq.com ~]# bash
[aaa@qq.com ~]# echo "$Product $Version" #子程序引用全局变量
Benet 6.0
[aaa@qq.com ~]# exit
[aaa@qq.com ~]# export S='door'
[aaa@qq.com ~]# echo $S
door
[aaa@qq.com ~]# bash
[aaa@qq.com ~]# echo $S
door
[aaa@qq.com ~]# exit
exit
[aaa@qq.com ~]# env
在其它用户登录进行测试,全局是否对用户有效
[aaa@qq.com ~]$ env
6.整数变量的运算
expr 变量1 运算符 变量2 [运算符 变量3] ...
6.1 常用运算符
加法运算:+
减法运算:-
乘法运算:\* (\:转义字符,回归本身意思)注意不能仅使用“*”符号,否则将被当成文件通配符
除法运算:/
求模(取余)运算:% 又称为取余运算,用来计算数值相除后的余数
元字符:具有特殊含义
示例:
两个数+、一、*、/、%的方法有三种
[aaa@qq.com ~]# expr 1 + 4
5
[aaa@qq.com ~]# echo $((1+4))
5
[aaa@qq.com ~]# echo $[1+4]
5
[aaa@qq.com ~]# expr 1 - 4
-3
[aaa@qq.com ~]# echo $[1-4]
-3
[aaa@qq.com ~]# echo $((1-4))
-3
[aaa@qq.com ~]# expr 1 \* 4
4
[aaa@qq.com ~]# echo $((1*4))
4
[aaa@qq.com ~]# echo $[1*4]
4
[aaa@qq.com ~]# expr 1 / 4
0
[aaa@qq.com ~]# echo $((1/4))
0
[aaa@qq.com ~]# echo $[1/4]
0
注:乘法在直接使用过程中是需要的,因为是shell正则表达式中的特殊字
符,所以需要转义字符\才能表示其真实含义,但是在(())和[]中不需要转义字
符。
[aaa@qq.com ~]# expr 1 % 4
1
[aaa@qq.com ~]# echo $((1%4))
1
[aaa@qq.com ~]# echo $[1%4]
1
7.特殊的Shell变量
1.环境变量
由系统提前创建,用来设置用户的工作环境
配置文件: /etc/profile、 ~/.bash_ profile(当前用户)
全局工作环境的变量,针对这个系统中所有用户都会指定
当前用户root指定
1.2 常见的环境变量
PWD、PATH
USER、SHELL、 HOME
示例:
改变系统环境变量
[aaa@qq.com ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[aaa@qq.com ~]# PATH="$PATH:/opt"
[aaa@qq.com ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/opt
2.只读变量
用于变量值不允许被修改的情况
[aaa@qq.com ~]# name=cloud
[aaa@qq.com ~]# readonly name //设置为只读变量
[aaa@qq.com ~]# echo $name
cloud
[aaa@qq.com ~]# name=yun
-bash: name: readonly variable //只读变量不可以被重新赋值
[aaa@qq.com ~]# unset name //只读变量不可以被删除
-bash: unset: name: cannot unset: readonly variable
示例:
[aaa@qq.com ~]# b=c
[aaa@qq.com ~]# readonly b
[aaa@qq.com ~]# unset b
-bash: unset: b: 无法反设定: 只读 variable
[aaa@qq.com ~]# b=yum
-bash: b: 只读变量
3.位置变量
表示为$n,n为1~9之间的数字
$0 $2,第2个位置参数
[aaa@qq.com ~]# ./myprog.sh one two three four five six
$1,第1个位置参数
[aaa@qq.com ~]# vi useradd.sh
[aaa@qq.com ~]# chmod +x useradd.sh
[aaa@qq.com ~]# ./useradd.sh ponmeng
[aaa@qq.com ~]# tail /etc/passwd
#!/bin/bash
#add user
useradd $1
passwd --stdin $1 < pass.txt
4.预定变量
$#:命令行位置变量的个数
$*:所有位置变量的内容 aaa@qq.com:变量内容
$?:上一条命令执行后返回的状态,当返回状态值为0时,表示执行正常,非0值表示执 行异常或出错
$0:当前执行的进程/程序名
在Shell中,aaa@qq.com和$*都表示命令行所有参数(不包括$0),但是$*将命令行的所有参数看成一个整体,而aaa@qq.com则区分各个参数。
示例:
[aaa@qq.com ~]# vi /etc/resolv.conf
[aaa@qq.com ~]# systemctl restart network
[aaa@qq.com ~]# ntpdate ntp.aliyun.com
[aaa@qq.com ~]# date
[aaa@qq.com ~]# vim bak.sh
[aaa@qq.com ~]# chmod +x bak.sh
[aaa@qq.com ~]# ./bak.sh /boot /etc /opt
已执行./bak.sh脚本
已执行3个对象备份
打包文件:/boot /etc /opt
#!/bin/bash
# 打包文件
g=bak-`date +%F`.gz
tar zcvf $g $* &> /dev/null
echo "已执行$0脚本"
echo "已执行$#个对象备份"
echo "打包文件:$*"
[aaa@qq.com ~]# vim bak.sh 编辑替换$*改为aaa@qq.com,查看效果
[aaa@qq.com ~]# ./bak.sh /boot /etc /opt
已执行./bak.sh脚本
已执行3个对象备份
打包文件:/boot /etc /opt
#!/bin/bash
# 打包文件
g=bak-`date +%F`.gz
tar zcvf $g aaa@qq.com &> /dev/null
echo "已执行$0脚本"
echo "已执行$#个对象备份"
echo "打包文件:$*"
[aaa@qq.com ~]# touch 1.txt
[aaa@qq.com ~]# echo $?
0
[aaa@qq.com ~]# cat sdaj
cat: sdaj: 没有那个文件或目录
[aaa@qq.com ~]# echo $?
1
上一个命令正确,$?为0
不正确,$?不为0
下一篇: 分布式 | DBLE 负载均衡方案