20 shell脚本编程1
一、杂项知识整理
1、脚本文件格式:
#!/bin/bash
(注释信息:)
#description:say hello
#vesion:1.4.
#author:Jerry
#date:20160718
(代码注释:)
(缩进 适度添加空白行)
shell脚本的用途有:
自动化常用命令
执行系统管理和故障排除
创建简单的应用程序
处理文本或文件
2、运行脚本的两种方式:
bash file.sh
chmod +x file.sh . file.sh
脚本调试:
bash -n 检查脚本中的语法错误
bash -x 调试执行,显示执行过程
3、变量:
变量:命令的内存空间
数据存储方式:
字符:
数值:整型,浮点型
作用:
数据存储格式
参与的运算
表示的数据范围
类型:
字符型
数值型:整型,浮点型
命名法则:
不能使用程序中的保留字如if for等
只能使用数字、字母及下划线,且不能以数字开头
见名知义
统一命名规则:驼峰命名法
4、bash中的算数运算:help let
+ – * / %取余 **乘方
实现算术运算:let var=算术表达式
var=$[expr]
赋值公式中等号两边不能有空格,有空格的是比较运算。
var=$((expr))
var=$(expr arg1 arg2 arg3…)
declare -i var=数值
echo ‘算数表达式’ | bc
乘法符号有些场景中需要转义,expr 3 \* 4,expr没有乘方运算
使用expr的时候需要每个字符串都加空格,否则识别为一个字符串:expr 1 + 3
使用bc命令可以使用计算器,重定向给计算器也可以进行计算,bc计算器可以直接使用正常算法格式如23+25,2^4等。
其中乘方使用bc如上,使用其他方式的时候是**,如
[root@centos68 tmp]# let a=2**4 [root@centos68 tmp]# echo $a 16
bash有内建的随机数生成器:$RANDOM(1-32767)
echo $[RANDOM%50] :0-49之间的随机数
echo $[RANDOM%50+1]:取余之后的结果加1,表示1-50之间的随机数。
5、增强型复制:
+= -= *= /= %= 自身进行运算之后再赋值给自己
自增自减:let var+=1
let var++
a++ 和 ++a是有区别的,运算顺序不一样
let var-=1
let var–
6、短路运算:
短路与:第一个为0,结果必定为0
第一个为1,第二个必须要参与运算
短路或:第一个为1,结果必定为1
第一个为0,第二个必须要参与运算
异或:^ 异或的两个值,相同为假,不同为真
7、两种聚集命令的方法:
复合式:date;who | wc -l 命令会一个接一个地运行
子shell:(date;who | wc -l) >>/tmp/trace 所有的输出都被发送给单个stdout和stderr。
8、测试命令:
test EXPRESSION
格式相同,就是去掉了括号
[ EXPRESSION ]
[[ EXPRESSION ]] EXPRESSION前后必须有空白字符
如test a = b [ a = b ] [[ a = b ]]
数值测试:
-gt 是否大于
-ge 是否大于等于
-lt 是否小于
-le 是否小于等于
-eq 是否等于
-ne 是否不等于
字符串测试:
== 是否等于
> 是否大于 acsii码
< 是否小于
!= 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配。注意,此表达式一般用于[[]]中
-z “string” 字符串是否为空,空为真,不空为假
-n “string” 字符串是否为不空,不空为真,空为假
注意:用于字符串比较时的用到的操作数都应该使用引号。
文件测试:
-a FILE 文件存在性测试,存在为假,否则为真
-e FILE 文件存在性测试,存在为真,否则为假
-b FILE 是否存在且为块设备文件
-c FILE 是否存在且为字符设备文件
-d FILE 是否存在且为目录文件
-f FILE 是否存在且为普通文件
-h FILE 或-L FILE 存在且为符号链接文件
-p FILE 是否存在且为管道文件
-S(大写) FILE 是否存在且为套接字文件
-r FILE 是否存在且可读
-w FILE 是否存在且可写
-x FILE 是否存在且可执行
检测的是实际权限,与显示的权限位不一定相同,例如root
-g FILE 是否存在且拥有sgid权限
-u FILE 是否存在且拥有suid权限
-k FILE 是否存在且拥有sticky权限
-s(小写) 是否有内容,有内容为真
-t fd:fd表示文件描述符是否已经打开且与某终端相关
-N FILE 文件自上一次被读取之后是否被修改过
-O FILE 当前有效用户是否为文件属主
-G FILE 当前有效用户是否为文件属组
双目测试:FILE1 -ef FILE2:两个文件是否指向同一个设备上的相同inode
FILE1 -nt FILE2 :FILE1是否新与FILE2
FILE1 -ot FILE2 : FILE1是否旧于FILE2
8、组合测试条件:
第一种方式:
COMMAND1 && COMMADN2 并且
COMMAND1 || COMMAND2 或者
!COMMAND 非
如:[ -e FILE ] && [ -r FILE ]
第二种方式:
EXPR1 -a EXPR2 并且
EXPR1 -o EXPR2 或者
!EXPR 非
必须使用测试命令进行
9、查看所有内部命令:man bash 或 enable
同名文件用mv和cp两个命令覆盖的区别:mv是改变了其索引,inode号没有变,也就是指元数据没变化。cp覆盖是新建了文件,数据也重新迁移,inode号也就改变了。
10、Linux中运行命令或者脚本,按照PATH变量给定的路径。windows先搜索当前目录再按照path变量寻找。
11、netstat -nt 查看活动网络连接;touch /etc/nologin,可以禁止普通用户登录!另外可以usermod -L和-U 以及passwd -l和-u进行禁止。
12、
二、练习及课后作业
1、变量类型及区别:
本地变量:生效范围是当前shell进程;对低昂前shell之外的其他shell进程,包括当前shell的子shell进程均无效。
赋值name=‘value’ 可以使用引用value,可以是直接字串name=“root”;变量引用:name=“$USER”;命令引用:name=`command` name=$(command)
变量引用:${name} $name
"" 弱引用,其中的变量引用会被替换为变量值
‘’强引用,其中的变量引用不会被替换为变量值
显示已定义的所有变量:set
删除变量:unset name(在脚本执行结束后一定要删除使用的变量以清空内存空间)
环境变量:生效范围为当前shell进程及子进程
环境变量:变量声明、赋值:export name=VALUE
declare -x name=VALUE
变量引用:$name $(name)
显示所有环境变量:export env printenv
删除:unset name
局部变量:生效范围为当前shell进程中某代码片段(通常指函数)
位置变量:$1,$2…来表示,用于让脚本代码中调用通过命令行传递给它的参数
只读变量:readonly name
declare -r name
也可以同时设置为环境变量
在脚本代码中调用通过命令行传递给脚本的参数
$1 $2…${10}…对应第1 第2…第10个参数,shift [n] 换位置
特殊变量:$?上一条命令的执行返回值,错误为0,正确为1-254
$0 脚本文件路径本身
$@ 传递给脚本的所有参数,每个参数为独立字符串
$# 显示使用了哪几个参数
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@和$*只在被双引号包起来时候才会有差异
2、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。
1 #!/bin/bash 2 #test 1 3 #info 4 5 echo "The hostname is : $(hostname)" 6 echo "The IP is: $(ifconfig | head -2 | tail -1 | tr -s " "| cut -d" " -f3)" 7 echo "The OS mode: $(cat /etc/system-release)" 8 echo "The kernel mode: $(uname -r)" 9 echo "The memory infomation: $(top | head -4 | tail -1 | cut -d: -f2)" 10 echo "The disk infomation : $(fdisk -l | grep "Disk /dev/sda:*" | cut -d, -f1 | cut -d: -f2)"
3、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中
1 #!/bin/bash 2 #test2 3 #bak 4 5 cp -rf /etc /root/etc$(date +%F) 6 #
4、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值
#!/bin/bash echo "The max using rate is:`df |grep "/dev/sd"| cut -c 44-46 | sort -nr | head -1`%" [root@centos68 shelltest]# bash disk.sh The max using rate is: 41%
5、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序。
#!/bin/bash #test 4 #Des echo "the links number is:" netstat -nt |tr -s ' ' |cut -d ' ' -f5 |cut -d: -f1 |grep [0-9]|sort |uniq -c|sort -nr
6、写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID和
#!/bin/bash #test 5 NUM1=`cat /etc/passwd | head -10 | tail -1 | cut -d: -f3` NUM2=`cat /etc/passwd | head -20 | tail -1 | cut -d: -f3` SUM=$[$NUM1+$NUM2] echo "The id sum is: $SUM" [root@centos68 shelltest]# bash -x sumid.sh ++ tail -1 ++ cut -d: -f3 ++ cat /etc/passwd ++ head -10 + NUM1=10 ++ cut -d: -f3 ++ tail -1 ++ cat /etc/passwd ++ head -20 + NUM2=499 + SUM=509 + echo 'The id sum is: 509' The id sum is: 509
7、写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
#!/bin/bash #version #Des #test 2 NUM1=`cat $1 | grep "^$" | wc -l` NUM2=`cat $2 | grep "^$" | wc -l` SUM=$[$NUM1+$NUM2] echo "space lines: $SUM" unset NUM1 NUM2 SUM
8、写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件
#!/bin/bash #test8 #Des:acount NUM1=`ls -a /etc/ | wc -l` NUM2=`ls -a /var/ | wc -l` NUM3=`ls -a /usr/ | wc -l` SUM=$[$NUM1+$NUM2+$NUM3] echo "The acount of all files :$SUM
原创文章,作者:SilencePavilion,如若转载,请注明出处:http://www.178linux.com/31941
评论列表(1条)
文章整体结构清晰,层次分明,通过练习对shelll脚本基础有了深刻的认识,希望能保持下去。