shell脚本必知会
来源:互联网 发布:淘宝和卖家联系 编辑:程序博客网 时间:2024/06/08 15:40
头部声明规范
#!/bin/bash#Author: wang#Version: 1.0#Date: 2016-05-01#Description:The script displays system informationecho "Greetings. The date and time are $(date)"echo "Your working directory is: $(pwd)"
bash
bash 和source执行脚本的区别
bash会开子shell执行,.和source会在当前shell执行
检测脚本中的语法错误bash -n /path/to/some_script
调试执行bash -x /path/to/some_script\
显示没条命令的结果及层级
脚本终止
当出现语法错误时脚本会终止执行,命令错误还是继续执行
让脚本可执行
- 给执行权限
- 用bash目录执行
- 放在/bin/bash目录
显示环境变量
- set(本地变量也会显示)
- export
- printenv
环境变量的声明
name='lee'sex=maleexport name sex # 或者用declare -x
常量的声明
name=leereadonly name 或者declare -r name
变量生效范围
- ==环境变量只对但前shell及下级shell有效,不会影响父shell==
- ==unset的变量只对但前shell及下级shell有效,不会影响父shell==
- ==父shell声明export变量后再unset,再重新以普通变量赋值,则子shell不再继承此变量==
- == 常量在子shell内无效(readonly 和 declare -r)==
true 与false
为内建命令
false # ?=1
! false #?=0 (==!与false之间有空格,每空格是执行历史命令==)
[ false ] # $?=0
bash位置变量
删除位置变量
- set –(不可用unset)
- shift n 先进先出,从$1开始删(出栈)
bash中的算术运算
x=100y=200let z=$x+$ylet z=x+yz=$[x+y]z=$[$x+$y]z=$((x+y))z=$(($x+$y))declare -i a=100 #声明int类型declare -i b=200declare -i c=a+b
==expr不能用来赋值,相当于计算器*需要转义==
增强型赋值(要用let赋值)
+=
-=
*=
/=
%=
:let count+=3(先增加3再赋值)
自增,自减:
- let var+=1
- let var++
- let var-=1
- let var–先减再赋值
- let –var 先赋值再减
==判断参数是否处理完根据shift执行结果来判断.处理一个shift一个,当最后一个出理完再shift的时候会返回1,因为没有参数拿来处理了==
条件测试
- test
- [] ==[ ” ” ]==空字符串为真(变量未定义为假)
- [[]] 特殊符号*等不用转义
字符串测试
| 变量 | 含义 |
| :—- | :—- |
== |是否等于;
|ascii 码是否大于ascii码 码
< | 是否小于
!= | 是否不等于
=~ |左侧字符串是否能够被右侧的PATTERN所 所 匹配
注意: 此表达式一般用于[[ ]] 中;扩展的正则表达式
[ -zx]−z如果为变量未定义返回真[−n“ x" ]或 [[ -nx]]未定义为真[[“ 1" == "$USER” ]] ==注意等号两边有空格则是判断字符串相等,每空格则是判断是否非空==
[ " " ] 真[ -z " " ][ "b" > "w" ] 正[ "b" \> "w" ] 假[ "btretr" \> "w" ] 假
== [] 里面用>要转义,字符串大小比较会以第一个字符的ascii码比较,符号字母直接要有空格;=~次符号两边不能有空格==
数值测试
注意:须使用[[]]
#判断用户是否存在 id user1 &> /dev/null && echo the user exist
练习
- 编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。
#!/bin/bash ~ 8 echo -e "\033[35m主机名:\033[0m \033[36m `hos ~ tname`\033[0m" ~ 9 sleep 2 ~ 10 echo -e "\033[35m系统版本:\033[0m \033[36m `u ~ name -r`\033[0m" ~ 11 sleep 1 ~ 12 echo -e "\033[35mipv4地址:\033[0m \033[36m `i ~ fconfig|grep -w inet|head -1|tr -s ' '|cut -d ~ ' ' -f3`\033[0m" ~ 13 echo -e "\033[35m内核版本:\033[0m \033[36m `c ~ at /etc/redhat-release`\033[0m" ~ 14 sleep 1 ~ 15 echo -e "\033[35mCPU型号:\033[0m \033[36m `ls ~ cpu| grep 'Model name'|cut -d: -f2|tr -s ' '` ~ \033[0m" ~ 16 sleep 1.5 ~ 17 echo -e "\033[35m硬盘空间:\033[0m \033[36m \n ~ `df -h|grep -v 'tmpfs'`\033[0m" ~ 18 sleep 1.5 ~ 19 echo -e "\033[35m内存大小:\033[0m \033[36m `f ~ ree `\033[0m"
编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中 中
编写脚本/root/bin/disk.sh, 显示当前硬盘分区中空间利用率最大的值
编写脚本/root/bin/links.sh, 显示正连接本主机的每个远程主机的IPv4
编写脚本/root/bin/sumid.sh ,计算/etc/passwd 文件中
的第10 个用户和第20 用户的ID 之和- 编写脚本/root/bin/sumspace.sh ,传递两个文件路径作
为参数给脚本,计算这两个文件中所有空白行之和 - 编写脚本/root/bin/sumfile.sh,统计/etc,/var,/usr目录中共有多少个一级子目录和文件
编写脚本/root/bin/argsnum.sh ,接受一个文件路径作为
参数;如果参数个数小于1 ,则提示用户“至少应该给一个参
数”,并立即退出;如果参数个数不小于1 ,则显示第一个参
数所指向的文件中的空白行数- 编写脚本/root/bin/hostping.sh ,接受一个主机的IPv4
地址做为参数,测试是否可连通。如果能ping 通,则提示用户
“该IP 地址可访问” ;如果不可ping 通,则提示用户“该IP地 地
址不可访问”
3 、编写脚本/root/bin/checkdisk.sh ,检查磁盘分区空间和inode使用率,如果超过80%,广播通知
存在性及类别测试
lrwxrwxrwx. 1 root root 7 Mar 21 16:42 lib -> usr/libll -d /usr/libdr-xr-xr-x. 27 root root 4096 Mar 31 03:33 /usr/lib[ -d /lib ] true[989][root@yongge: /]# [ -L /lib ] true[990][root@yongge: /]# [ -h /lib ] true[991][root@yongge: /]# [ -b /lib ] false==注意判断软连接时,会同时判断软连接和软连接指向的文件====权限是以最终权限为判据的==
判断权限之前先判断存在性
[ -e FILE -a -r FILE ]
()和{}中逻辑代码的区别
==()包含的逻辑代码会开子进程执行;{}包含的逻辑直接在父进程执行==
例如如下两个脚本:
# 脚本一[ -e file1 ] || ( echo 'file1 not exit' && exit 2)echo 'continue'# 脚本2:[ -e file1 ] || { echo 'file1 not exit' ; exit 2}echo 'continue'
脚本一中遇到exit只是退出了子进程,所以echo continue会继续执行;脚本2中不会执行{}部分是一个匿名函数,故用分号隔开
双目测试
FILE1 -ef FILE2: FILE1 与FILE2 是否指向同一个设备上
的相同inode
FILE1 -nt FILE2: FILE1 是否新于FILE2
FILE1 -ot FILE2: FILE1 是否旧于FILE2
组合测试条件
- && || !
如:[[ -r FILE ]] && [[ -w FILE ]] 或者[ -r FILE -a -w FILE ]
- -a -o ! (不能使用[[]]进行测试)
[ ! -w /etc/passwd ] 不可写
[ -z “
“localhost.localdomain” ] && hostname www.magedu.com
[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
设置颜色
格式 echo -e “\033[ 字背景颜色(40-47);文字颜色(30-37)m 字符串\033[0m”
Eg :echo -e “\033[41;36m something here \033[0m”
41 的位置代表底色, 36 的位置是代表字的颜色
字体颜色:30——37
echo -e “\033[30m 黑色字 \033[0m”
echo -e “\033[31m 红色字 \033[0m”
echo -e “\033[32m 绿色字 \033[0m”
echo -e “\033[33m 黄色字 \033[0m”
echo -e “\033[34m 蓝色字 \033[0m”
echo -e “\033[35m 紫色字 \033[0m”
echo -e “\033[36m 天蓝字 \033[0m”
echo -e “\033[37m 白色字 \033[0m”
1. 编写脚本/bin/per.sh, 判断当前用户对指定的参数文件,是否不可读并且不可写2. 编写脚本/root/bin/excute.sh ,判断参数文件是否为sh后缀的普通文件,如果是,添加所有人可执行权限,否则提示用户非脚本文件3. 编写脚本/root/bin/nologin.sh 和login.sh, 实现禁止和充许普通用户登录系统
参数替换和扩展
字符串操作
${#string}
$string的 长度 ${string:position}
在${string:position:length}
在${string#substring}
从 变量${string##substring}
从 变量${string%substring}
从 变量${string%%substring}
从 变量${string/substring/replacement}
使用${string//substring/replacement}
使 用${string/#substring/replacement}
如 果${string/%substring/replacement}
如果expr match "$string" '$substring'
匹配expr "$string" : '$substring'
匹 配expr index "$string" $substring
在expr substr $string $position $length
在expr match "$string" '\($substring\)'
从expr "$string" : '\($substring\)'
从expr match "$string" '.*\($substring\)'
从expr "$string" : '.*\($substring\)'
从s=www.baidu.www.com# 删除指定字符(#从头开始匹配删,%从结尾开始匹配删)echo ${s#w*}ww.baidu.www.comecho ${s##w*} #全部删除echo ${s##*.}comecho ${s%.*}www.baidu.wwwecho ${s%%.*}www# 查找替换(支持通配符*?[])echo ${s/www/ttt}ttt.baidu.www.comecho ${s/w/t}tww.baidu.www.comecho ${s//w/t}ttt.baidu.ttt.comecho ${s//*/t}techo ${s//w*/t}techo ${s//./t}wwwtbaidutwwwtcomecho ${s//\./t}wwwtbaidutwwwtcomecho ${s//w./t}wwtbaidu.wwtcomecho ${s/w./t}wwtbaidu.www.comecho ${s/w?/t}tw.baidu.www.comecho ${s//w?/t}ttbaidu.ttcomecho ${s/[a-z]/t}tww.baidu.www.comecho ${s//[a-z]/t}ttt.ttttt.ttt.tttecho ${s/[^a-w]/t}wwwtbaidu.www.comecho ${s//[^a-w]/t}wwwtbaidutwwwtcom# 计算长度的2中方法:echo ${#s}17expr length $s17# 获取包含字符在原串中的索引expr index $s 'www' #获取www第一次出现的位置(从1开始)1
==$substring是一个正 则表达式.==
长度计算
- ${#var}
- expr length var
截取
索引截取 ${var:index:length}
匹配截取
替换
- 只替换第一个 ${var/reg/str}把reg匹配的部分替换成str
- 全部替换 {var//reg/str}
删除
- ${var%%reg}删除reg匹配的部分
变量容错
变量批量赋值
read x y z < /etc/issue
[root@yongge: /root]# read x y z <<<"111 222 333"[root@yongge: /root]# echo $x111[root@yongge: /root]# echo $y222[root@yongge: /root]# echo $z333[root@yongge: /root]# read a b c <<<"$x $y $z"[root@yongge: /root]# echo $a111[root@yongge: /root]# echo $b222[root@yongge: /root]# echo $c333
bash命令执行顺序
- 把命令行分成单个命令词
- 展开别名
- 展开大括号种的声明({}) )
- 展开波浪符声明(~) )
- 命令替换$() 和 “) )
- 再次把命令行分成命令词
- 展开文件通配(* 、? 、[abc] 等等)
- 准备I/0 重导向(< 、>) )
- 运行命令
if语句
if condition;then actionfiif contionthen actionfiif condition1;then action1else action2fiif condition1then action1else action2fi//多条件then不能换行写if condition1;then action1elif contion2;then action2fiif condition1;then action1elif contion2;then action2else action3fi
for循环
for i in x;do actiondonefor i;i<n;i++;do actiondone
unit循环
unit condition;do actiondone
select循环
select var in list do action done
while 语句
while i<n;do action let n--donewhile read line;do echo $linedone < /etc/passwd
function
语法-: function fname{ }语法二:function fname(){}语法三:fname(){}语法四:{}
- shell脚本必知会
- php面向对象必知会
- linux必知会之文件操作
- 产品设计必知会的10个人性心理
- 产品经理必知会的时间管理术
- sql必知会学习心得:mysql附带资源的导入
- 零基础学习ui设计必知会的一些事儿
- 前端知会 之 Fiddler反向代理HTML嵌入JS脚本
- 嵌入式新人必知会的linux与ARM开发板学习建议
- 黑客进阶必读书《Linux命令行与Shell脚本编程大全》(第2版)
- shell必学命令
- shell必知
- shell必懂知识点
- shell脚本
- shell脚本
- shell脚本
- shell脚本
- shell脚本
- c++ 用模板和异或实现交换任何类型值
- nv12 图像的旋转
- 五大常用算法:动态规划
- 初识Linux-Linux下的三个时间参数(atime、mtime、ctime)
- mybatis逆向工程 优就业
- shell脚本必知会
- js和jquery获取父级元素、子级元素、兄弟元素的方法
- ActivexObject 区分IE浏览器与非IE浏览器
- Web基础之CSS实战
- 基于Tiny4412的Linux按键输入子系统驱动的实现(一)
- dpkg:警告:无法找到软件包(dpkg -l | grep ^ii | awk '{print $2}' | grep -v xxxx | grep -v xxxx| xargs sudo apt)
- 学习记录
- java ‘方法’简解
- UE4的NetWork简单原理