Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。
对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Linux系统的关键。
※ shell 脚本基础:
包含一些命令或声明,并符合一定格式的文本文件
格式要求:首行shebang 机制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
shell 脚本的用途有:
自动化常用命令
执行系统管理和故障排除
创建简单的应用程序
处理文本或文件
※创建shell脚本
第一步:使用文本编辑器来创建文本文件
·第一行必须包括shell 声明序列:#!
#!/bin/bash
·添加注释 注释以# 开头
·第二步:运行脚本
·给予执行权限,在命令行上指定脚本的绝对或相对路径
·直接运行解释器,将脚本作为解释器程序的参数运行
脚本代码开头约定
1 、第一行一般为调用使用的语言
2 、程序名,避免更改文件名为无法找到正确的文件
3 、版本号
4 、更改后的时间
5 、作者相关信息
6 、该程序的作用,及注意事项
7 、最后是各版本的更新简要说明
※
检测脚本中的语法错误
bash -n /path/to/some_script
调试 执行
bash -x /path/to/some_script
※ 本地变量
变量赋值:name=‘value’
※ 环境变量
变量声明、赋值: export name=VALUE
declare -x name=VALUE
变量引用: $name, ${name}
显示所有环境变量:
env
printenv
export
declare -x
删除变量 : unset name
※ 只读变量
readonly varname
declare -r varname
查看所有的只读变量
readonly -p
※ 位置变量
位置变量:在脚本代码中调用通过命令行传递给脚本的参数
$1, $2, ...:对应第1、第2等参数,shift [n]换位置
$0: 命令本身
$*: 传递给脚本的所有参数,全部参数合为一个字符串
$@: 传递给脚本的所有参数,每个参数为独立字符串
$#: 传递给脚本的参数的个数
$@ $* 只在被双引号包起来的时候才会有差异
set -- 清空所有位置变量
注意:当位置参数达到10以后,要加大括号。
※ bash中的算术运算:help let
+, -, *, /, %取模(取余), **(乘方)在bc当中乘方是^
实现算术运算:
(1) let var=算术表达式
(2) var=$[算术表达式]
(3) var=$((算术表达式))
(4) var=$(expr arg1 arg2 arg3 ...) 乘法时要转译* ,即\* expr $x \* $y
l
(5) declare –i var = 数值
(6) echo ‘算术表达式’ | bc
※ 逻辑运算
与:
真与真 真
真与假 假
假与真 假
假与假 假
只要有一个假则为假
短路与 前一个为假,则不再判断第二个值。
或
真或真 真
真或假 真
假或真 真
假或假 假
只要有一个真则为真
短路或,前一个为真,则不再判断第二个值
※ 条件性的执行操作
根据退出状态而定,命令可以有条件地运行
&& 代表条件性的AND THEN
|| 代表条件性的OR ELSE
※bash的数值测试
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
字符串测试:
== 是否等于
> ascii 码是否大于ascii码 码
< 是否 小于
!= 是否 不等于
=~ 左侧 字符串是否能够被右侧的PATTERN所 所 匹配
注意: 此表达式一般用于` `,扩展的正则表达式
用于字符串比较时的用到的操作数都应该使用引号
※ 习题
1.编写脚本/root/bin/backup.sh,可实现将/etc/目录备份到/root/etcYYYY-mm-dd中。
解析:-a保留所有的属性权限等 $引用变量 date +%F :年月日
2.编写脚本/root/bin/sumid.sh ,计算/etc/passwd 文件中的第10 个用户和第20 用户的ID之和
解析:这道题可以用head和tail来截取第十行和第二十行;也可以用cat -n给文件标注行数,再用grep截取所需的行,除此之外,都用到tr和cut.但我在做这道题时等号前留了空格,于是脚本就一直出现错误。$1是位置参数。
3 、编写脚本/root/bin/sumfile.sh, 统计/etc, /var, /usr目录中共有多少个一级子目录和文件
解析:此题用了位置参数$1,$2,$3,还用了引用变量。
4.编写脚本/root/bin/sumspace.sh ,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和。
5.编写脚本/root/bin/argsnum.sh ,接受一个文件路径作为参数;如果参数个数小于1 ,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1 ,则显示第一个参数所指向的文件中的空白行数
答案:[[ $1 == "" ]]&& echo "至少应该给一个参数" && exit ||grep -c "^[[:space:]]&" $1|wc -l
解析:此题用到了位置参数$1;条件性执行操作:&&: 条件性的and then
||:条件性的or else
2.编写脚本/root/bin/hostping.sh ,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping 通,则提示用户“该IP 地址可访问” ;如果不可ping通,则提示用户“该IP地 地址不可访问”
答案:ping -c1 -w1 $1 &> /dev/null && echo 该ip地址可访问||echo 该ip地址不可访问
解析:-c1:只ping一个 -w1:超时等待一秒 如果ip地址ping得通的话就导给垃圾桶,不通的话就提示用户。
7.编写脚本/root/bin/checkdisk.sh ,检查磁盘分区空间和inode 使用率,如果超过80% ,就发广播警告空间将满。
答案:disk=`df|grep "/dev/sd"|sort -nr -k5|tr -s " " "%"|cut -d% -f5|head -1`
inode=`df -i|grep "/dev/sd"|sort -nr -k5|tr -s " " "%"|cut -d% -f5|head -1`
[[ $disk -gt 80 ]] && wall the disk will full||echo the disk is not more than 80%
[[ $inode -gt 80 ]] && wall the inode will full||echo the inode is not more than 80%
解析:与上面几题相比,此题用到了数值测试:-gt 是否大于 其他的用到的都是文本截取工具之类的。