shell编程
shell基础介绍
shell编程的意义
为什么使用shell编程
节约时间
显示脚本执行过程
前面有+表示执行过的命令的
前面没有东西,表示输出到屏幕上的内容。
[root@nfsnobody scripts]# sh bak-etc-adv.sh
tar: Removing leading `/' from member names
[root@nfsnobody scripts]# sh -x bak-etc-adv.sh
++ hostname -I
++ awk '{print $1}'
+ ip=10.0.0.200
+ mkdir -p /backup/10.0.0.200
++ date +%F
+ tar zcf /backup/10.0.0.200/etc-2018-08-17.tar.gz /etc/
tar: Removing leading `/' from member names
变量
什么是变量
x + y = 10 x=20 y=? 未知数(变量)
变量命名规则
变量命名规则: 不能以数字开头
ip=10.0.0.200
赋值(把数据存放在变量中)
[root@nfsnobody /server/scripts]# echo $ip 查看变量内容
10.0.0.200
[root@nfsnobody /server/scripts]# 1ip=10.0.0.200 无法设置变量
-bash: 1ip=10.0.0.200: command not found
变量分类
普通变量(局部变量)
环境变量(全局变量)
特殊变量:(重点)
普通变量(局部变量)
用=可以配置局部变量
如ip=10.0.0.200
[root@nfsnobody /server/scripts]# ip=10.0.0.200 设置普通变量
[root@nfsnobody /server/scripts]# echo $ip 查看变量内容
10.0.0.200
环境变量(全局变量)
大写的
系统定义的
在大部分地方可以使用
env命令可以查看所有的环境变量
export 设置环境变量
unset 取消环境变量
目前已经学习过的有PATH PS1 LANG
取env的第一列内容(回顾)
env可以查看所有的环境变量
[root@CentOS scripts]# env
[root@CentOS scripts]# env |awk -F "=" '{print $1}'
[root@CentOS scripts]# env |sed -r 's#=.*##g'
[root@CentOS scripts]# env | egrep -o '^[A-Z0-9_]+'
[root@CentOS scripts]# env | egrep -o '^[^=]+'
普通变量与全局变量的区别
[root@nfsnobody /server/scripts]# nfsnobody=10 配置一个普通变量
[root@nfsnobody /server/scripts]# echo $nfsnobody 查看变量
10
[root@nfsnobody /server/scripts]# cat show.sh 脚本的内容
echo $nfsnobody
[root@nfsnobody /server/scripts]# sh show.sh 执行 没有变量的内容
[root@nfsnobody /server/scripts]# sh -x show.sh 显示执行过程 没有
+ echo
[root@nfsnobody /server/scripts]# export nfsnobody=10 配置成全局变量(环境变量)
[root@nfsnobody /server/scripts]# sh -x show.sh 有结果了
+ echo 10
10
[root@nfsnobody /server/scripts]# env |grep -i nfsnobody 配置成全局变量 在env也可以查到
HOSTNAME=nfsnobody
nfsnobody=10
[root@CentOS scripts]# cat show.sh 查看脚本内容
#!/bin/bash
echo $nfsnobody
[root@CentOS scripts]# nfsnobody=10 配置nfsnobody的变量 普通变量
[root@CentOS scripts]# env |grep old 检查env是否有nfsnobody的全局变量 检查没有发现
[root@CentOS scripts]# source show.sh 使用source 可以使局部变量在脚本内生效
10
[root@CentOS scripts]# . show.sh 局部变量生
10
[root@CentOS scripts]# sh show.sh 使用sh局部变量没有生效
特殊变量(重点)
特殊变量介绍
$1 $2 表示 第一个 第二个参数
$# 表示参数的个数
$? 表示上一个命令执行后的状态
状态为0 表示执行正确
状态非0 表示执行错误
$0 表示文件名
特殊变量小结:
$1 $2 $数字 awk:第1列 第2列 第3列
shell脚本:第1个参数
$0 awk:整行
shell脚本:文件名
$# 脚本的参数个数
判断脚本的参数个数
$? 上一个命令的执行结果(返回值)
0 执行正确
非0 执行失败
特殊变量测试
{}的用处
[root@nfsnobody /server/scripts]# week=6 配置一个变量
[root@nfsnobody /server/scripts]# echo $week 查看
6
想要在变量后面加上天数显示6day
[root@nfsnobody /server/scripts]# echo $weekday
[root@nfsnobody /server/scripts]# echo ${week}day
6day
$1 $2
第1个参数 第2个参数
[root@nfsnobody /server/scripts]# cat cal.sh 查看脚本内容
#!/bin/bash
n1=$1
n2=$2
awk -vnum1=$n1 -vnum2=$n2 'BEGIN{print num1+num2 }'
awk -vnum1=$n1 -vnum2=$n2 'BEGIN{print num1-num2 }'
awk -vnum1=$n1 -vnum2=$n2 'BEGIN{print num1*num2 }'
awk -vnum1=$n1 -vnum2=$n2 'BEGIN{print num1/num2 }'
[root@nfsnobody /server/scripts]# sh cal.sh 10 20
执行脚本 10表示第一个变量$1 20表示的是$2
30
-10
200
0.5
$0的使用
$0 shell脚本中表示文件名
[root@CentOS scripts]# cat cal-read.sh
#!/bin/bash
echo "当前编辑的文件为: $0"
[root@CentOS scripts]# sh cal-read.sh
当前编辑的文件为: cal-read.sh
$? 的使用
$? 表示上一个命令执行后的状态
状态为0 表示执行正确
状态非0 表示执行错误
[root@nfsnobody ~]# aaa 执行一个字符
-bash: aaa: command not found 执行失败
[root@nfsnobody ~]# echo $? 查看$?
127 非0 表示上一个命令执行错误执行错误
[root@nfsnobody ~]# sh /server/scripts/show2.sh aa bb
aa bb 2
[root@nfsnobody ~]# echo $? 0表示上一个命令执行成功
0
$#的使用
$# 表示参数的个数
脚本内容
[root@nfsnobody ~]# cat /server/scripts/show2.sh
#!/bin/bash
echo 112 $#
if [ $? == 0 ];then
echo "OK"
fi
执行的不同结果
[root@nfsnobody ~]# sh /server/scripts/show2.sh 1 2 3 4 6 5个参数 $# 显示参数的个数
1 2 5 表示一个五个参数
[root@nfsnobody ~]# sh /server/scripts/show2.sh aa bb 2个参数 $# 显示参数的个数
aa bb 2 两个参数
[root@nfsnobody ~]# sh /server/scripts/show2.sh aa bb cc 3个参数 $# 显示参数的个数
aa bb 3 三个参数
awk的变量
命令行中的变量 放在awk中 无法直接使用 需要用awk的方式重新定义变量
用-v重新定义变量 如-vnum1=10
书写一个计算器 加减乘除
变量中 把两个数字放在变量中
[root@nfsnobody /server/scripts]# n1=10 在命令行定义变量n1
[root@nfsnobody /server/scripts]# n2=20 在命令行定义变量n2
[root@nfsnobody /server/scripts]# awk 'BEGIN{print n1/n2}' 使用awk计算
awk: fatal: division by zero attempted 报错无法执行
[root@nfsnobody /server/scripts]# awk 'BEGIN{print n1,n2}'
显示也无法显示 变量不可用
[root@nfsnobody /server/scripts]# awk -vnum1=10 'BEGIN{print num1 }'
10
[root@nfsnobody /server/scripts]# awk -vnum1=10 -vnum2=20 'BEGIN{print num1/num2 }'
0.5
书写脚本计算10与20的加减乘除
cal.sh
#!/bin/bash
n1=10
n2=30
awk -vnum1=$n1 -vnum2=$n2 'BEGIN{print num1+num2 }'
awk -vnum1=$n1 -vnum2=$n2 'BEGIN{print num1-num2 }'
awk -vnum1=$n1 -vnum2=$n2 'BEGIN{print num1*num2 }'
awk -vnum1=$n1 -vnum2=$n2 'BEGIN{print num1/num2 }'
awk -v {num1=$n1,num2=$n2} 'BEGIN{print num1/num2 }' 也可以这种写法
vim快捷键
批量删除
批量增加
1.进入批量编辑模式(可视块)
2.选择 批量增加的范围
3.按 shift + i 进行修改
4.按esc 退出等等
ctrl + v 按d批量删除
ctrl + v 按x批量删除
dd 删除光标所在行
dG 删除光标所在行到最后一行
D 光标所在位置到行尾的内容
x 删除光标所在位置的一个字符
read命令
通过read 交互式
read交互式赋予变量内容
read -p "提示信息:" 变量名字
read -p "提示信息:" p
执行之后会把输入的信息存放在变量中
-p 为显示提示信息。p作为输出,一定要写在其他参数的最后面。
-t5 等待5秒
-s 输入的时候不显示输入内容。
[root@nfsnobody ~]# read a 定义变量
呵呵 此处是输入的内容
[root@nfsnobody ~]# echo $a 查看变量
呵呵
让执行命令后出现提示信息
-p 为显示提示信息。p作为输出,一定要写在其他参数的最后面。
[root@nfsnobody ~]# read -p "请输入:" a
请输入:呵呵
[root@nfsnobody ~]# echo $a
呵呵
设置等待(超时)的时间
-t5 等待5秒
[root@nfsnobody ~]# read -t5 -p "请输入密码:" a
请输入密码:
[root@nfsnobody ~]#
[root@nfsnobody ~]# read -t5 -p "请输入密码:" a
请输入密码:123
不显示输入的内容
-s 输入的时候不显示输入内容。
[root@nfsnobody ~]# read -s -t50 -p "请输入密码:" a
请输入密码:
[root@nfsnobody ~]# echo $a
admin
将read命令运用到脚本上
修改计算器脚本的内容,让他能够更智能。
[root@nfsnobody ~]# vim /server/scripts/cal.sh
#!/bin/bash
read -p "input 1st num:" a 写入read命令的内容
read -p "input 2st num:" b
测试脚本
[root@nfsnobody ~]# sh /server/scripts/cal.sh
input 1st num:1 输入1
input 2st num:2 输入2
0.5
3
-1
2
read同时读入多个字符
[root@nfsnobody ~]# read -p "输入第一个 第二关数字:" a b
输入第一个 第二关数字:123 456
[root@nfsnobody ~]# echo aab
123 456
修改脚本的内容。
使用一条read命令,读取两个参数。
[root@nfsnobody ~]# vim /server/scripts/cal.sh
#!/bin/bash
read -p "input 1st&2st num:" a b
awk -vnum1=a−vnum2=a−vnum2=b 'BEGIN{print num1/num2}'
awk -vnum1=a−vnum2=a−vnum2=b 'BEGIN{print num1+num2}'
awk -vnum1=a−vnum2=a−vnum2=b 'BEGIN{print num1-num2}'
awk -vnum1=a−vnum2=a−vnum2=b 'BEGIN{print num1*num2}'
"/server/scripts/cal.sh" 15L, 355C written
测试脚本。
同时传入两个参数的时候,参数之间要使用空格分割.
[root@nfsnobody ~]# sh /server/scripts/cal.sh
input 1st&2st num:1 2
0.5
3
-1
2
判断
判断一个 文件/目录 是否存在
符号 | 参数 | 含义 | 英文 |
---|---|---|---|
> | -gt | 大于 | great than |
>= | -ge | 大于等于 | great equal |
< | -lt | 小于 | less than |
<= | -le | 小于等于 | less than or equal |
== | -eq | 等于 | equal |
!= | -ne / ! -eq | 不等于 | not equal |
test命令
test命令不会自己输出执行的结果
配合$?查询上一条命令是否执行成功,就能够判断是否存在这个文件或目录.
判断文件是否存在
-f 为判断的对象是文件,0为存在,1为不存在
[root@nfsnobody ~]# test -f /nfsnobody/nfsnobody.txt 使用test -f命令 查看文件是否存在
[root@nfsnobody ~]# echo $? 查看变量
0 存在
[root@nfsnobody ~]# test -f /nfsnobody/nfsnobody 查看文件是否存在
[root@nfsnobody ~]# echo $? 查看变量
1 不存在
判断目录是否存在
-d 为对目录进行判断,0为存在,1为不存在.
[root@nfsnobody ~]# test -d /nfsnobody 使用test -d命令 查看目录是否存在
[root@nfsnobody ~]# echo $? 查看变量
1 不存在
[root@nfsnobody ~]# test `-d /nfsnobody/ 使用test -d命令 查看目录是否存在
[root@nfsnobody ~]# echo $? 查看变量
0 存在
使用[ ]判断
使用[ ]的时候注意中间的空格,两边都要有两个空格
[ ]与test命令的功能相似,可以进行判断,相比test命令更为便捷
判断文件是否存在
与test命令一样 [ ] 判断的结果也0为存在,1为不存在
-f 为判断的对象是文件
[root@nfsnobody ~]# [ -f /zinx.txt ] 查看nfsnobody.txt文件是否存在
[root@nfsnobody ~]# echo $? 查看上一条命令的执行结果
1 不存在
[root@nfsnobody ~]# [ -f /root/nfsnobody.txt ] 查看/root/nfsnobody.txt文件是否存在
[root@nfsnobody ~]# echo $? 查看上一条命令的执行结果
0 存在
判断文件/目录是否存在,判断成功执行后面的内容,输出ok ;判断失败,不执行后面的命令.
[root@nfsnobody ~]# [ -f /nfsnobody/nfsnobody.txt ] && echo "ok"
##/nfsnobody/nfsnobody.txt该文件不存在 所以没有执行后面的命令 所以没有结果
[root@nfsnobody ~]# [ -d /nfsnobody ] && echo "ok" 该目录存在 所以执行了后面的命令 输出OK
ok
如果这个文件不存在,就创建 (使用 || ), || 前面命令执行错误,才执行后面的命令.
[root@nfsnobody ~]# [ -f /nfsnobody/nfsnobody.txt ] || touch /nfsnobody/nfsnobody.txt
前面文件不存在 执行错误 执行了后面的 创建了/nfsnobody/nfsnobody.txt 文件
[root@nfsnobody ~]# ls -l /nfsnobody/nfsnobody.txt
-rw-r--r-- 1 root root 0 Sep 20 10:31 /nfsnobody/nfsnobody.txt
如果/root/nfsnobodydir 目录不存在就创建
[root@nfsnobody ~]# [ -d /root/nfsnobodydir ] || mkdir -p /root/nfsnobodydir
[root@nfsnobody ~]# ls -ld /root/nfsnobodydir
drwxr-xr-x 2 root root 4096 Sep 20 10:36 /root/nfsnobodydir
如果/root/nfsnobodydir 目录不存在,就创建这个目录
[root@nfsnobody ~]# [ ! -d /root/nfsnobodydir/1 ] && mkdir -p /root/nfsnobodydir/1
使用 && ,前面的执行成功,执行后面的; ! 表示非,不存在.
[root@nfsnobody ~]# ll -d /root/nfsnobodydir/1
drwxr-xr-x 2 root root 4096 Sep 20 10:41 /root/nfsnobodydir/1
判断在脚本的使用
如果 [ 这个文件存在 ];然后
提示文件存在
否则
创建这个文件
果如
判断文件是否存在,不存在就创建
写入脚本的时候,注意脚本的基本格式.
[root@nfsnobody ~]# vim /server/scripts/if.sh
#!/bin/bash
if [ -f /root/nfsnobody.txt ];then
echo "文件存在"
else
touch /root/nfsnobody.txt
fi
[root@nfsnobody ~]# sh /server/scripts/if.sh 测试脚本
文件存在
在脚本中进行判断的格式
如果cal2.sh脚本的参数个数不等于2,就显示 "命令错误"
书写脚本
!= 表示判断两个是否不相等,如果不相等就显示命令错误
#/bin/bash
if [ $# != 2 ];then
echo "命令错误"
fi
对脚本进行测试.
[root@nfsnobody ~]# sh /server/scripts/cal2.sh
##当参数的个数为2的时候,不会输出,个数不为二的时候输出 命令错误
命令错误
[root@nfsnobody ~]# sh /server/scripts/cal2.sh 1 2
[root@nfsnobody ~]# sh /server/scripts/cal2.sh 1 2 3
命令错误
修改计算机的脚本
修改之前的计算器,进行两个数字的加减乘除,在计算器前面加上参数个数判断。当输入的参数是2个的时候执行计算,不为2的时候显示参数错误.
当输入的参数不为2的时候 执行 echo "Usage: NUM1 NUM2", 然后执行 exit..
exit 表示前面的执行完成后就结束(跳出),不会再执行脚本后面的内容.
[root@nfsnobody ~]# vim /server/scripts/cal2.sh
#!/bin/bash
if [ $# -ne 2 ];then
echo "Usage: NUM1 NUM2"
exit
fi
a=$1
b=$2
awk -vh=a−vz=a−vz=b 'BEGIN{print h/z}'
awk -vh=a−vz=a−vz=b 'BEGIN{print h+z}'
awk -vh=a−vz=a−vz=b 'BEGIN{print h-z}'
awk -vh=a−vz=a−vz=b 'BEGIN{print h*z}'
测试脚本
当输入的参数个数不为2的时候执行echo 命令
当输入的参数个数为2的时候进行计算
[root@nfsnobody ~]# sh /server/scripts/cal2.sh
Usage: NUM1 NUM2 ##提示信息
[root@nfsnobody ~]# sh /server/scripts/cal2.sh 22 22
1
44
0
484