一、编程基础:
shell脚本是包含一些命令或声明,并符合一定格式的文本文件
shell脚本的用途有:
-
自动化常用命令
-
执行系统管理和故障排除
-
创建简单的应用程序
-
处理文本或文件
1) 第一步:使用文本编辑器来创建文本文件 script.sh 并编写内容
格式要求:首行shebang 指明所要使用的shell类型
#!/bin/bash #!/usr/bin/python #!/usr/bin/perl
结合命令、变量、表达式、语句等编写脚本内容
“#”号开头的行为注释行
#echo something echo "test txte"
2) 第二步:运行脚本
给予执行权限,在命令行上指定脚本的绝对或相对路径
]#chmod +x script.sh ]#./script.sh
直接运行解释器,将脚本作为解释器程序的参数运行
]#bash script.sh
#bash:调试执行脚本
-n 简单检查脚本语法错误
-x 调试执行,显示脚本运行过程
二、变量:
变量类型:
1)本地变量:作用域仅为当前shell进程
变量的定义:
用户定义的变量有字母数字及下划线组成,
变量名的第一个字符不能为数字.
变量名是大小写敏感的
变量的引用:
${name},$name
" ": 双引号 变量名会替换为其值
' ' :单引号 变量名不会替换
查看变量:set
撤销变量:unset name
2)环境变量:作用域为当前变量及其子进程 对其他登录用户无效
变量赋值:
export name=value
declare -x name=value
bash内嵌了很多环境变量(一般为全大写),用于定义bash工作环境
PATH,HISTFILE,HISTSIZE,SHELL,HOME,UID,OLDPWD
查看环境变量:export;declare -x;printenv;env
撤销环境变量:unset name
3)局部变量:作用域为某代码片段 函数上下文
4)只读变量(常量)
declare -r name
readonly name
只读变量无法重新设定,不支持撤销,当前shell终止后撤销
5)特殊变量
$0 脚本文件路径本身 basename
$#:参数个数
$*:所有参数 "chen he zhao" 所有参数合并为单个字符串
$@:所有参数 "chen" "he" "zhao"
位置变量:
向脚本传递位置参数变量:
scrip.sh argu1 argu2
对应
$1,$2…${10},${11}…
轮替:
shift# 去掉前#个参数 即${#+1}变成$1
数据类型:字符型,数值型
三、数值运算:
算术运算: + – * / % ^ *乘法有时需要转义
let var=expr
$[expr]
$((expr))
$(expr argu1 argu2 argu3
增强型赋值:
let
i+=# :i=$i+#
i-=
i*=
i/=
i%=
自增/自减:
let VAR=$($VAR+1)
let VAR+=1
let VAR++
—
]#i=1 ]#let i++ ]#echo $i ]#2 ]#let i+=2 ]#echo $i ]#4 ]#expr 3 + 4]#expr 3 \* 4]#echo 3*4|bc
四、逻辑运算:
运算数:真(true,yes,on,1)
假(false,no,off,0)
1.与
1 && 1 = 1
1 && 0 = 0
0 && 1 = 0
0 && 0 = 0
2.或
1 || 1 = 1
1 || 0 = 1
0 || 1 = 1
0 || 0 = 0
3.非
! 1 = 0
! 0 = 1
4.异或
真真 假
真假 真
1)CMD1 && CMD2 如果真…就…
CMD1为假 则CMD2不运行
CMD1为真 则CMD2运行
2)CMD1 || CMD2 如果假…就…
CMD1为真 则CMD2不运行
CMD1为假 则CMD2运行
五、bash测试类型:
测试表达式:
test EXPRESSION
[ EXPRESSION ] 表达式两端须有空格
[[ EXPRESSION ]]
1.数值测试: [ $num1 -## $num2 ] 整数测试!
-eq:等于
-ne:不等于
-gt:大于
-ge:大于等于
-lt:小于
-le:小于等于
]#[ 5 -gt 4 ]&&echo 0 ]#0
2.字符串测试: [[ "CHAR" # "CHAR" ]] ASCLL码比较
==:是否等于
>: 大于 ascll 编码
<: 小于
!=:不等于
=~:左侧字符串 是否能够被右侧 模式匹配
* -z "STRING":判断变量是否为空;空位真,不空为假
-n "STRING":判断是否不空 空为假,不空为真
]#[[ root =~ r.*t ]]&&echo 0 ]#0
3.文件测试:
存在性测试:
-a FILE
-e FILE
存在为真
文件类型测试:[ -# /PATH/FILE ]
-b 存在且为 块设备
-c 存在且为 字符设备文件
-d 存在且为 目录
-f 存在且为 普通文件
-p 存在且为 管道文件
-S 存在且为 套接字文件
-h|L 存在且为 符号链接文件
]#[ -d /etc ] && echo 0
]#0
4.文件权限测试: 以用户 实际权限; root用户存在特权
000 但对root可读 可写 不可执行
-r 存在且 对当前用户可读
-w 存在且 对当前用户可写
-x 存在且 对对当前用户可执行
-特殊权限测试:
-u 存在且有 suid
-g 存在且有 sgid
-k 存在且有 stick
-文件是否非空:
* -s 不空为真,空为假
-时间戳:
-N 文件自最近被读后是否被修改过
-从属关系测试:
-O 当前用户是否 为文件属主
-G 当前用户是否 属于文件属组
-双目测试:mtime 判断修改时间
FILE1 -ef FILE2 是否互为硬链接
* FILE1 -nt FILE2 F1是否新于F2
FILE1 -ot FILE2 F1是否旧于F2
-a = 且
-o = 或
]#a=6 ]#[ $a -gt 0 -a $a -lt 9 ] && echo 0 ]#0
六、脚本的状态返回值:
默认脚本执行的最后一条命令的状态返回值;
自定义状态退出状态码;
exit [n]: n 对应 $? 的值
shell进程遇到exit 即结束 n=[0-255]
利用命令状态返回值判断:
0:成功
1-255:失败
#read [OPTION] 获取用户输入信息,从而完成变量赋值
-p ""设置提示信息
-t # 设置超时时间
]#read -p "please enter a number:" num ]#please enter a number:5 ]#echo $num ]#5
====作业
一、脚本
1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。
#!/bin/bash printf %-10s "hostname:" echo "`hostname`" printf %-10s "ip:" echo "`ifconfig|sed -nr 's/.*r:(.*) B.*/\1/p'`" printf %-10s "kernel:" echo "`uname -r|tr ':' ':\t'`" printf %-10s "OS:" echo "OS:\t\t`cat /etc/redhat-release`" printf %-10s "CPU:" echo "`lscpu|grep "Model name"|tr -d " "|cut -d: -f2`" printf %-10s "Mem:" echo "free|sed -n 2p|tr -s ' '|cut -d' ' -f2" printf %-10s "DiskSize:" echo "`lsblk|sed -n 2p|tr -s " "|cut -d " " -f4`"
2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中
#!/bin/bash cp -a /etc /testdir/etc$(date +%F)&>/dev/null&&echo cp success||echo cp failuer
3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值
#!/bin/bash echo "the max usage:`df|grep '/dev/sd.*'|tr -s ' '|cut -d' ' -f5|sort|tail -1`"
4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序
#!/bin/bash netstat -t|tr -s ' ' ':'|cut -d: -f6|grep [0-9]|sort|uniq -c|sort -nr
5、写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和
!/bin/bash ID1=`sed -n ${1}p /etc/passwd|cut -d: -f3` ID2=`sed -n ${2}p /etc/passwd|cut -d: -f3` let sum=ID1+ID2 echo "sum:$sum"
6、写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
#!/bin/bash blank1=`grep "^$" $1|wc -l` blank2=`grep "^$" $2|wc -l` let sum=blank1+blank2 echo "sum=$sum"
7、写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件
#!/bin/bash s1=`ls /etc|wc -l` s2=`ls /var|wc -l` s3=`ls /usr|wc -l` sum=$[s1+s2+s3] echo "sum=$sum"
8、写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数
#!/bin/bash echo -n "please enter a path:" read path [ ! -e $path ] && echo "file does not exist" && exit 5 || grep -c "^[[:space:]]*$" $path #[[ $# -lt 1 ]] && echo "at least one arg" && exit 5 || grep -c "^[[:space:]]*$" $1
9、写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”
#!/bin/bash read -p "please ernter a ip adddress:" addr ping $addr -W1 -c1&>/dev/null && echo "IP address rechable!" || echo "IPaddress unrechable!"
10、判断硬盘的每个分区空间和inode的利用率是否大于80,如果是,发邮件通知root磁盘满
#!/bin/bash disk=`df |grep "/dev/sd.*"|cut -c 44-46|sort -nr|head -1` inode=`df -i|grep "/dev/sd.*"|cut -c 40-42|sort -nr|head -1` [ $disk -gt 80 -o $inode -gt 80 ]&&echo 'disk fulling'|mail root||echo dont worry
11、指定文件做为参数,判断文件是否为.sh后缀,如果是,添加x权限
#!/bin/bash [ ! -e $1 ]&&echo "file dose not exist!"&&exit 23 [[ $1 =~ .*\.sh$ ]]&&chmod +x $1&&echo '+x done'||echo not sh
12、判断输入的IP是否为合法IP
#!/bin/bash echo -n "please enter a ip:" read ip echo $ip|egrep -q "^(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>\.){3}(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>)$" && echo legal ip || echo illegal ip
13、计算1+2+3+…+100
#!/bin/bash seq -s '+' 1 100|bc
14、输入起始值A和最后值B,计算从A+(A+1)…+(B-1)+B的总和
#!/bin/bash seq -s '+' $1 $2|bc
原创文章,作者:Jasper,如若转载,请注明出处:http://www.178linux.com/34844