Shell脚本编程基础
?程序
?程序:算法+数据结构
?数据:是程序的核心
?数据结构:数据在计算机中的类型和组织方式
?算法:处理数据的方式
?程序编程风格:
过程式:以指令为中心,数据服务于指令
对象式:以数据为中心,指令服务于数据
?shell程序:提供了编程能力,解释执行
高级编程语言:
编译:高级语言-->编译器-->机器代码-->执行
C,C++
解释:高级语言-->执行-->解释器-->机器代码
shell,python,php,JavaScript,perl
编译语言:像吃大餐,做好再吃,从执行角度看,效率高。
解释语言:像吃火锅,边吃边做,从开发角度看,效率高。
shell脚本基础
?shell脚本:
包含一些命令或声明,并符合一定格式的文本文件
?格式要求:首行shebang机制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
?shell脚本的用途有:
?自动化常用命令
?执行系统管理和故障排除
?创建简单的应用程序
shell脚本示例
#!/bin/bash
------------------------------------------
Filename: hello.sh
Revision: 1.1
Date: 2017/06/01
Author: wang
Email: [email protected]
Website: www.magedu.com
Des处理文本或文件
脚本调试?检测脚本中的语法错误
bash -n /path/to/some_script?
调试执行bash -x /path/to/somescri
变量
?Shell中变量命名法则:
1、不能使程序中的保留字:例如if, for
2、只能使用数字、字母及下划线,且不能以数字开头
3、见名知义
4、统一命名规则:驼峰命名法
?Shell中命名建议规则:
1、变量名大写
2、局部变量小写
3、函数名小写
4、用英文名字,并体现出实际作用
bash中变量的种类
根据变量的生效范围等标准划分下面变量类型
局部变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,
包括当前shell的子shell进程均无效
环境变量:生效范围为当前shell进程及其子进程
本地变量:生效范围为当前shell进程中某代码片断,通常指函数
位置变量:$1, $2, ...来表示,用于让脚本在脚本在脚本代码中调用通过命令行传递给它的参数
特殊变量:$?, $0, $*, [email protected], $#,$$
练习
1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小
2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到
/root/etcYYYY-mm-dd中
3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值
4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序
环境变量
bash内建的环境变量:PATH SHELL USER UID HOME ?PWD SHLVL LANG MAIL HOSTNAME HISTSIZE 下划线
只读和位置变量
? 只读变量:只能声明,但不能修改和删除
? 声明只读变量:
readonly name
declare -r name
? 查看只读变量:
readonly -p
位置变量:在脚本代码中调用通过命令行传递给脚本的参数
$1, $2, ... 对应第1、第2等参数,shift [n]换位置
$0 命令本身
$ 传递给脚本的所有参数,全部参数合为一个字符串
[email protected] 传递给脚本的所有参数,每个参数为独立字符串
$# 传递给脚本的参数的个数
注意:[email protected] $ 只在被双引号包起来的时候才会有差异
set -- 清空所有位置变量
退出状态
进程使用退出状态来报告成功或失败
0 代表成功,1-255代表失败
$? 变量保存最近的命令退出状态
?例如:
ping -c1 -W1 hostdown &> /dev/null
echo $?
算术运算
bash中的算术运算:help let
+, -, *, /, %取模(取余), **(乘方),乘法符号有些场景中需要转义
实现算术运算:
(1) let var=算术表达式
(2) var=$[算术表达式]
(3) var=$((算术表达式))
(4) var=$(expr arg1 arg2 arg3 ...)
(5) declare –i var = 数值
(6) echo ‘算术表达式’ | bc
bash有内建的随机数生成器变量:$RANDOM(0-32767)
示例:生成 0 - 49 之间随机数
echo $[$RANDOM%50]
?短路运算
短路与
第一个为0,结果必定为0
第一个为1,第二个必须要参与运算
短路或
第一个为1,结果必定为1
第一个为0,第二个必须要参与运算
?异或:^
异或的两个值,相同为假,不同为真
条件性的执行操作符?根据退出状态而定,命令可以有条件地运行? && 代表条件性的AND THEN? || 代表条件性的OR ELSE?例如:grep -q no_such_user /etc/passwd \
|| echo ‘No such user‘ No such userping -c1 -W2 station1 &> /dev/null \
&& echo "station1 is up" \
|| (echo ‘station1 is unreachable‘; exit 1)
station1 is up
test命令
长格式的例子:
test "$A" = "$B" && echo "Strings are equal"
test “$A”-eq “$B” && echo "Integers are equal"
?简写格式的例子:
[ "$A" = "$B" ] && echo "Strings are equal"
[ "$A" -eq "$B" ] && echo "Integers are equal"
bash的数值测试
?-v VAR
变量VAR是否设置
?数值测试:
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
bash的字符串测试
?字符串测试:
= 是否等于
ascii码是否大于ascii码
< 是否小于
!= 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配
注意: 此表达式一般用于[[ ]]中;扩展的正则表达式
-z "STRING“ 字符串是否为空,空为真,不空为假
-n "STRING“ 字符串是否不空,不空为真,空为假
注意:用于字符串比较时的用到的操作数都应该使用引号
read -p “Enter a filename: “ FILE
条件选择if语句
?选择执行:
?注意:if语句可嵌套
?单分支
if 判断条件;then
条件为真的分支代码
fi
?双分支
if 判断条件; then
条件为真的分支代码
else
条件为假的分支代码
Fi
If示例
?根据命令的退出状态来执行命令
if ping -c1 -W2 station1 &> /dev/null; then
echo ‘Station1 is UP‘
elif grep "station1" ~/maintenance.txt &> /dev/null; then
echo ‘Station1 is undergoing maintenance‘
else
echo ‘Station1 is unexpectedly DOWN!‘
exit 1
Fi
条件判断:case语句
case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
)
默认分支
;;
esac
find查找 tar压缩 部分
查找条件
根据属主、属组查找:
-user USERNAME:查找属主为指定用户(UID)的文件
-group GRPNAME: 查找属组为指定组(GID)的文件
-uid UserID:查找属主为指定的UID号的文件
-gid GroupID:查找属组为指定的GID号的文件
-nouser:查找没有属主的文件
-nogroup:查找没有属组的文件
查找空文件或目录:find /app -type d -emp
?德·摩根定律:
(非 A) 或 (非 B) = 非(A 且 B)
(非 A) 且 (非 B) = 非(A 或 B)
?示例:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)
示例:找出/tmp目录下,属主不是root,且文件名不以f开头的文件
find /tmp ( -not -user root -a -not -name ‘f‘ ) -ls
find /tmp -not ( -user root -o -name ‘f‘ ) –ls
?排除目录
?示例:
查找/etc/下,除/etc/sane.d目录的其它所有.conf后缀的文件
find /etc -path ‘/etc/sane.d’ -a –prune -o -name “.conf”
查找/etc/下,除/etc/sane.d和/etc/fonts两个目录的所有.conf后缀的文件
find /etc ( -path "/etc/sane.d" -o -path "/etc/fonts" ) -a -prune -o -
name ".conf"
根据权限查找:根据权限查找:
-perm [/|-]MODE
MODE: 精确权限匹配
/MODE:任何一类(u,g,o)对象的权限中只要能一位匹配即可,或关系,+ 从centos7开始淘汰
-MODE:每一类对象都必须同时拥有指定权限,与关系
0 表示不关注
? find -perm 755 会匹配权限模式恰好是755的文件
? 只要当任意人有写权限时,find -perm +222就会匹配
? 只有当每个人都有写权限时,find -perm -222才会匹配
? 只有当其它人(other)有写权限时,find -perm -002才会匹配
?有些命令不能接受过多参数,命令执行可能会失败,xargs可以解决
?替换参数xargs示例:
ls f |xargs rm
find /sbin/ -perm +700 |ls -l 这个命令是错误的
find /bin/ -perm /7000 | xargs ls -l 查找有特殊权限的文件
find /bin/ -perm -7000 | xargs ls -l 此命令和上面有何区别?
?find和xargs格式:find | xargs COMMAND
?备份配置文件,添加.orig这个扩展名
find -name “.conf” -exec cp {} {}.orig \;
?提示删除存在时间超过3天以上的joe的临时文件
find /tmp -ctime +3 -user joe -ok rm {} \;
?在主目录中寻找可被其它用户写入的文件
find ~ -perm -002 -exec chmod o-w {} \;
?查找/data下权限为644,后缀为sh的普通文件,增加执行权限
find /data –type f -perm 644 -name “.sh” –exec chmod 755 {} \;
?查看/home的目录
find /home –type d -ls
压缩:gunzip file.gz 解压缩
zcat file.gz 不显式解压缩的前提下查看文本文件内容
bunzip2 file.bz2 解压缩
bzcat file.bz2 不显式解压缩的前提下查看文本文件内容
?unxz file.xz 解压缩
?xzcat file.xz 不显式解压缩的前提下查看文本文件内容
打包压缩
zip –r /backup/sysconfig /etc/sysconfig/
解包解压缩
unzip sysconfig.zip
cat /var/log/messages | zip messages -
unzip -p message > message
Tar:tar -cpvf /PATH/FILE.tar FILE... 创建归档
tar -r -f /PATH/FILE.tar FI 追加文件至文档
查看归档文件中的文件列表
tar -t -f /PATH/FILE.tar
(4) 展开归档
tar -x -f /PATH/FILE.tar
tar -x -f /PATH/FILE.tar -C /PATH/
(5) 结合压缩工具实现:归档并压缩
-j: bzip2, -z: gzip, -J: xz
文件查找工具sed
|sed -r ‘[email protected](./)([^/]+)/[email protected]\[email protected]‘ 取基名
|sed -r ‘[email protected](./)([^/]+)/[email protected]\[email protected]‘ 取目录名
使用sed命令取IPV4地址:
1、|sed -n ‘2p‘ |sed -r ‘s/inet//‘ |sed -r ‘s/netmask.//‘ |tr -d " "
2、|sed -n ‘2p‘ sed -e ‘s/^.inet//‘ -e ‘s/.//‘
3、|sed -n -e ‘2s/^.inet//‘ -e ‘2s/ .//p‘
4、|sed -nr ‘[email protected]inet (.) .n.@\[email protected]‘
5、|sed -nr ‘2s/[^0-9]+([0-9.]+).*/\1/p‘
原文地址:http://blog.51cto.com/14128387/2338029