在一些复杂的Linux维护工作中,大量重复性的输入和交互操作不但费时费力,而且容易出错。
而编写一个恰到好处的shell脚本程序,可以批量处理,自动化的完成一系列维护任务,大大减轻管理员的负担。
开发语言简单举例:shell,Python,Java,JavaScript,HTML,CSS
强语言:定义变量时需要声明数据类型:如Java,C语言等
int age=10 强语言,静态语言,
整型:int ,如1 ,2 ,3, ,100,等
长整型:Long
浮点型:float
单精度,4字节,如3.1
双精度,double,8字节, 3.14
String:字符串
char ,字符 ‘a’ 1字节(Java中 ‘a’ 2字节),'男’2字节
boolean,布尔值,true成了 or false不成立
date,日期
int a=10;
弱语言:不需要声明,如shell,JavaScript,Python
a=10
a=10.1
HTML,标记语言,标签, ,xml文件格式
枚举:限定一个范围
json,键:值,key:value,a:10
shell变量直接定义,不需要声明
shell脚本的概念
将要执行的命令按顺序保存到一个文件文本
给该文件可执行权限,便可运行
可结合各种shell控制语句以完成更复杂的操作
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
使用vim文本编辑器
每行一条Linux命令,按执行顺序依次编写
脚本后缀为.sh
例如,将一下三条命令按顺序用shell脚本编写
cd /boot
pwd
ls
[root@ shanan ~]# vi first.sh
wq 退出保存,一个脚本就编写OK了
方法一:./ 脚本文件路径,方法需要先给脚本增加执行权限
[root@ shanan ~]# vi first.sh
[root@ shanan ~]# chmod +x first.sh
[root@ shanan ~]# ./first.sh
/boot
config-3.10.0-957.el7.x86_64 initramfs-3.10.0-957.el7.x86_64kdump.img
efi symvers-3.10.0-957.el7.x86_64.gz
grub System.map-3.10.0-957.el7.x86_64
grub2 vmlinuz-0-rescue-677e01449522468c88f8c55390ba4628
initramfs-0-rescue-677e01449522468c88f8c55390ba4628.img vmlinuz-3.10.0-957.el7.x86_64
initramfs-3.10.0-957.el7.x86_64.img
[root@ shanan ~]# sh first.sh
/boot
config-3.10.0-957.el7.x86_64 initramfs-3.10.0-957.el7.x86_64kdump.img
efi symvers-3.10.0-957.el7.x86_64.gz
grub System.map-3.10.0-957.el7.x86_64
grub2 vmlinuz-0-rescue-677e01449522468c88f8c55390ba4628
initramfs-0-rescue-677e01449522468c88f8c55390ba4628.img vmlinuz-3.10.0-957.el7.x86_64
initramfs-3.10.0-957.el7.x86_64.img
[root@ shanan ~]# source first.sh
/boot
config-3.10.0-957.el7.x86_64 initramfs-3.10.0-957.el7.x86_64kdump.img
efi symvers-3.10.0-957.el7.x86_64.gz
grub System.map-3.10.0-957.el7.x86_64
grub2 vmlinuz-0-rescue-677e01449522468c88f8c55390ba4628
initramfs-0-rescue-677e01449522468c88f8c55390ba4628.img vmlinuz-3.10.0-957.el7.x86_64
initramfs-3.10.0-957.el7.x86_64.img
[root@ shanan ~]# . first.sh
/boot
config-3.10.0-957.el7.x86_64 initramfs-3.10.0-957.el7.x86_64kdump.img
efi symvers-3.10.0-957.el7.x86_64.gz
grub System.map-3.10.0-957.el7.x86_64
grub2 vmlinuz-0-rescue-677e01449522468c88f8c55390ba4628
initramfs-0-rescue-677e01449522468c88f8c55390ba4628.img vmlinuz-3.10.0-957.el7.x86_64
initramfs-3.10.0-957.el7.x86_64.img
脚本声明
注释信息
可执行语句
[root@ shanan ~]# ./first.sh
当前的目录位于:
/boot
目录中有如下内容:
config-3.10.0-957.el7.x86_64 initramfs-3.10.0-957.el7.x86_64kdump.img
efi symvers-3.10.0-957.el7.x86_64.gz
grub System.map-3.10.0-957.el7.x86_64
grub2 vmlinuz-0-rescue-677e01449522468c88f8c55390ba4628
initramfs-0-rescue-677e01449522468c88f8c55390ba4628.img vmlinuz-3.10.0-957.el7.x86_64
initramfs-3.10.0-957.el7.x86_64.img
标准输入:从该设备接收用户输入的数据
标准输出:通过该设备向用户输出数据
标准错误输出 /dev/stderr 2 显示器
错误输出
[root@ shanan ~]# cat abc.tct 2> error.txt
[root@ shanan ~]# cat error.txt
cat: abc.tct: 没有那个文件或目录
[root@ shanan ~]# cat abc.tct > error02.txt
cat: abc.tct: 没有那个文件或目录
[root@ shanan ~]# cat error02.txt
[root@ shanan ~]# cat abc.tct 2> error.txt
[root@ shanan ~]# cat error.txt
cat: abc.tct: 没有那个文件或目录
[root@ shanan ~]# cat abc.tct > error02.txt
cat: abc.tct: 没有那个文件或目录
混合输出
[root@ shanan ~]# cat error02.txt
[root@ shanan ~]# grep "bash$" /etc/passwd &> user.txt
[root@ shanan ~]# cat user.txt
root:x:0:0:root:/root:/bin/bash
test1:x:1000:1000::/home/test1:/bin/bash
test2:x:1001:1001::/home/test2:/bin/bash
test3:x:1002:1002::/home/test3:/bin/bash
[root@ shanan ~]# grep "wangwu$" /etc/passwd &> user02.txt
[root@ shanan ~]# cat user02.txt
[root@ shanan ~]# cat acv &> user02.txt
[root@ shanan ~]# cat user02.txt
cat: acv: 没有那个文件或目录
[root@ shanan ~]#
将输出导入黑洞,不让信息输出
[root@ shanan ~]# yum install httpd -y &> /dev/null
[root@ shanan ~]# rpm -q httpd
httpd-2.4.6-93.el7.centos.x86_64
Awk -F 列的控制,段落的控制 F:表示分割符号,冒号 ,如果不写,默认以空格和制表符作为标识 ,单引号作为分割的内容,print 打印 , 第一列和第七列
查看磁盘容量使用情况
[root@ shanan ~]# df -hT | awk '{print$1,$6}'
文件系统 已用%
/dev/mapper/centos-root 12%
devtmpfs 0%
tmpfs 0%
tmpfs 2%
tmpfs 0%
/dev/sdb1 1%
/dev/sda1 15%
/dev/mapper/centos-home 1%
tmpfs 0%
[root@ shanan ~]#
awk :大部分情况,按列读取
大部分情况下
grep:过滤关键字
sed: 按行读取
awk:按列读取数据
变量的作用
为灵活管理Linux系统提供特定参数,有两层意思
变量名:使用固定的名称,由系统预设或用户定义
变量值:能够根据用户设置,系统环境的变化而变化
变量的类型
自定义变量:由用户自己定义,修改和使用
环境变量:由系统维护,用于设置工作环境
位置变量:通过命令行给脚本程序传递参数
预定义变量:bash中内置的一类变量,不能直接修改
变量名以字母或下划线开头,区分大小写,建议全大写
变量名=变量值
代表将右边的值赋予左边
查看变量的值:echo $变量名
[root@ shanan ~]# x=8
[root@ shanan ~]# echo $x
8
[root@ shanan ~]# num=1
[root@ shanan ~]# name=ky
[root@ shanan ~]# echo $name$ky
ky
[root@ shanan ~]# echo $name$num
ky1
赋值时使用引号
双引号:允许通过$符号引用其他变量值
单引号:禁止引用其他变量值,$视为普通字符
反撇号:命令替换,提取命令执行后的输出结果
[root@ shanan ~]# num=1
[root@ shanan ~]# num3="test $num" //'双引号:允许通过$符号引用其他变量值'
[root@ shanan ~]# echo $num3
test 1
[root@ shanan ~]# num3='test $num'
[root@ shanan ~]# echo $num
1
[root@ shanan ~]#
[root@ shanan ~]# num4=`ps aux | wc -l`
[root@ shanan ~]# echo $num4
157
或
[root@ shanan ~]# num=$(ps aux | wc -l)
[root@ shanan ~]# echo num
num
[root@ shanan ~]# echo $num
157
[root@ shanan ~]# num=1
[root@ shanan ~]# num3='test $num' //单引号禁止引用其他变量值,$视为普通字符
[root@ shanan ~]# echo $num3
test $num
[root@ shanan ~]# num4=`ps aux | wc -l` //'反撇号中识别命令,对命令结果进行解析'
[root@ shanan ~]# echo $num4
157
或
[root@ shanan ~]# num=$(ps aux | wc -l) // $() 对括号内的命令进行解析
[root@ shanan ~]# echo num
num
[root@ shanan ~]# echo $num
157
[root@ shanan ~]# read -p "请输入一个整数:" sum
请输入一个整数:120
你输入的值是: 120
格式一:export 变量名…
格式二:export 变量名=变量值…
两种格式可以混合使用
Bash 切换新的环境
全局变量export
readonly 变量 名 将变量设为只读,防止篡改
[root@ shanan ~]# export num=8
[root@ shanan ~]# bash
[root@ shanan ~]# echo $num
8
将变量设为只读,防止被篡改
[root@ shanan ~]# echo $num
1
[root@ shanan ~]# readonly num
[root@ shanan ~]# echo $num
1
[root@ shanan ~]# unset num
-bash: unset: num: 无法反设定: 只读 variable
整数变量的运算
expr 变量1 运算符 变量2 [运算符 变量3]…
1
常用运算符
加法运算:+
减法运算:-
乘法运算:*
除法运算:/
求模(取余)运算:%
[root@ shanan ~]# expr 3 + 2 '正确格式,加法运算'
5
[root@ shanan ~]# expr 3 - 2 '正确格式,减法运算'
1
[root@ shanan ~]# expr 3 \* 2 '正确格式,乘法运算'
6
[root@ shanan ~]# expr 3 / 2 '正确格式,除法运算'
1
[root@ shanan ~]# expr 3 % 2 '正确格式,取余运算'
1
[root@ shanan ~]# expr 32 % 21
11
[root@ shanan ~]# expr 32 % 5
2
[root@ shanan ~]]# sum=`expr 3 + 3` '正确格式,求和变量运算'
[root@ shanan ~]# echo $sum
6
[root@ shanan ~]# vi sum.sh
[root@ shanan ~]# sh sum.sh
请输入一个整数:5
请输入第二个整数:6
和为:11
环境变量
由系统提前创建,用来设置用户的工作环境
配置文件:/etc/profile,~/.bash_profile
常见的环境变量
PWD,PATH
USER,SHELL,HOME
表示为$n,n为1-9之间的数字
$1,$2:位置变量
[root@ shanan ~]# sh sum.sh 5 6
和为:11
#!/bin/bash
#name
sum=0
sum=`expr $1 + $2 `
echo "是否执行成功:$?"
echo "和为:$sum "
echo "执行的脚本是$0"
echo "执行的脚本个数是:$#"
echo "详细内容是:$*"
~
[root@ shanan ~]# sh sum.sh 5 6
和为:11
[root@ shanan ~]# vi sum.sh
[root@ shanan ~]# sh sum.sh 5 6
是否执行成功:0
和为:11
执行的脚本是sum.sh
执行的脚本个数是:2
详细内容是:5 6
$#:命令行中位置变量的个数
$*:所有位置变量的内容
$?:上一条命令执行后返回的状态,当返回状态值为0时表示正常,非0值表示执行异常或出错
$0:当前执行的进程/程序名
分析脚本
[root@ shanan ~]# vim sss.sh
#!/bin/bash
TARFILE=beifen-`date +%s`.tgz '设置变量名称,+%s表示从1970至今经过的秒数,所以文件名不会出现重复的情况,就不会有被覆盖的风险'
tar zcvf $TARFILE $* &> /dev/null 'tar工具压缩输出到 /dev/null'
echo "已执行$0个脚本" '当前执行的进程名'
echo "共完成$#个对象的备份" '位置变量的个数'
echo "具体内容包括:$*" '所有位置变量的内容'
~
[root@ shanan ~]# ./sss.sh /etc/passwd /etc/shadow
已执行./sss.sh个脚本
共完成2个对象的备份
具体内容包括:/etc/passwd /etc/shadow
'/dev/null:黑洞,数据到这里就消失了,无法找回'
将本地文件归档并上传到服务器192.168.100.100
首先在本地SSH进行设置,进行密钥对登录,使用BASH代理,免登录,然后操作
#!/bin/bash
#定义归档文件名称
FILENAME=file-`date +%s `.tar.gz
#归档操作
tar zcvf /opt/$FILENAME /root/abc*
scp /opt/$FILENAME root@192.168.100.100:/opt/
[root@ shanan ~]# sh bk.sh
tar: 从成员名中删除开头的“/”
/root/abc1.txt
/root/abc2.txt
/root/abc3.txt
/root/abc4.txt
/root/abc5.txt
/root/abc6.txt
/root/abc7.txt
/root/abc8.txt
/root/abc9.txt
file-1594908687.tar.gz 100% 184 104.6KB/s 00:00
[root@shanan opt]# ll
总用量 18204
-rw-r--r-- 1 root root 4 6月 19 11:35 2.txt
drwxr-xr-x 2 root root 6 6月 15 15:51 a
drwxr-xr-x 2 root root 6 6月 15 16:13 b
-rw-r--r-- 1 root root 5900 7月 16 21:50 file-1594907445.tar.gz
-rw-r--r-- 1 root root 184 7月 16 22:11 file-1594908687.tar.gz