前言 unix/linux操作系统下的shell,是一种壳,其目的是提供一个用户与计算机相互交互的命令接口,通过输入各种命令,达到操作的目的。 与此同时,shell支持控制流程,进而可以组合出各种各样的应用实例。
shell脚本的格式
首行shebang机制:
bash脚本,首行添加#!/bin/bash [options]
csh脚本,首行添加#!/bin/csh [options]
ksh脚本,首行添加#!/bin/ksh [options]
……
描述脚本的注释部分:
包括Author, Version, Date, Description,……该部分是非必须项,目的是为了让使用脚本的人能够比较清晰地了解该脚本的背景以及功能
脚本的正文部分:
包含命令与声明,以面向过程的形式组合在一起
脚本示例如下:
编写脚本的一些规范
1. 脚本的第一行shebang注明调用的语言
2. 注释上一些信息,诸如: 文件名,功能描述,作者,版本……
3. 变量名和函数名建议使用同一种命名法则
4. 有尽量多的注释说明程序的功能,单行注释写在代码行上部或者尾部
5. 代码做的修改要加必要的版本注释和功能说明
6. 脚本的控制流程里面建议要有缩进,使用一定数量的空格或者Tab
7. 文件名按照使用的语言,以.sh,.pl,.py等形式为后缀
常用的符号
符号
描述
”
在单引号中所有特殊符号均无特殊含义
“”
在双引号中,除“$”“\”外其他特殊符号都无特殊含义
$()
在括号中使用系统命令
$
调用变量的值
\
转义符
$n
代表命令行的第n个参数,其中$0代表命令本身
$#
代表命令行中参数的个数
$*
代表命令行中所有的参数,把所有参数看成一个整体
$@
代表命令行中的所有参数,把每个参数个别对待
$?
代表最后一次执行的命令的返回状态,返回0代表执行成功,否则不成功
$$
代表当前进程的进程号
$!
代表后台运行的最后一个进程的进程号
变量
* 用户自定义变量 *:
为局部变量,只对当前shell生效。默认类型为字符串类型。
定义:变量名=变量值,当变量中含有空格时,需要用引号引起来
声明:declare [+/-] [option] 变量名
选项: +取消属性 -设置属性 -i 整型 -a 数组 -r 只读
使用<code>unset</code>命令删除变量
更加详细的声明规则,可以使用help declare查询
* 数组 *:
定义数组: arr_name=(value1 value2 ….)或 使用arr_name[index]=value单独为元素赋值
注意:
数组元素放在小括号内,而不是大括号,元素之间使用空格分开,而不是逗号,元素下标从0开始
获取数组元素: {arr_name[index]} 索引号为index的元素 {array_name[*]}数组的所有元素
获取数组长度: ${#arr_name[*]}
数组切片:${arr_name[@]:start:length}
元素匹配替换:${arr_name[@]/before/after}
* 环境变量 *:
为全局变量,对子shell仍然有效,一般定义为大写,使用命令<code>env</code>或者<code>set</code>命令可以查询,用命令<code>declare -x</code>可以自定义环境变量,使用<code>unset</code>命令可以删除变量。常用的系统预定义的环境变量如下所示:
变量
$PATH
命令的搜寻路径
$OLDPWD
前一个工作目录
$LANG
目前的工作环境语言
$BASH
目前使用的shell的绝对路径(默认为/bin/bash)
$BASH_VERSION
使用的shell解释器的版本
$HISTCONTROL
控制历史记录,常用的有ignoredups,erasedups,ignorespace,……
$OSTYPE
显示系统类型
存放mail的文件
$MAILCHECK
多久检查一下邮件
$PWD
当前路径
$SSH_TTY
当前登录的TTY
$SHLVL
当前SHELL在第几层
$RANDOM
输出一个随机整数
注:生成0-49之间的随机数可以用如下命令:
算数运算
bash支持简单的算数运算,实现方式如下:
let r=9+9
r=$[9+9]; r=$[VAR1+VAR2]
r=$((9+9)); r=$((VAR1+VAR2))
expr 8 + 3
declare -i r=9+9
echo “9+9” | bc
赋值 可以使用如下几种赋值符号: =, +=, -=, *=, /=, %= 使用示例如下:
字体颜色
字体颜色示例如下:
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”
带背景的字体示例如下:
echo -e “\033[40;37m 黑底白字 \033[0m” echo -e “\033[40;37m 红底白字 \033[0m” echo -e “\033[40;37m 绿底白字 \033[0m” echo -e “\033[40;37m 黄底白字 \033[0m” echo -e “\033[40;37m 蓝底白字 \033[0m” echo -e “\033[40;37m 紫底白字 \033[0m” echo -e “\033[40;37m 天蓝底白字 \033[0m” echo -e “\033[40;37m 白底黑字 \033[0m”
条件判断
使用<code>test</code>命令或者<code>[]</code>或者<code>[[]]</code>对条件进行测试
关于文件的判断,使用方式如下:
判断符
解释
-e
判断文件是否存在,如果存在则为真
-d
判断文件是否存在并且是否是目录(目录是一种特殊的文件),是则返回真
-f
判断文件是否存在并且是普通文件,是则返回真
-r
判断文件是否存在并且执行判断的用户是否对该文件有读的权限,是则返回真
-w
判断文件是否存在并且执行判断的用户是否对该文件有写的权限,是则返回真
-x
判断文件是否存在并且执行判断的用户是否对该文件有执行的权限,是则返回真
-nt
判断前面的文件是否比后面的文件新,是则返回真
-ot
判断前面的文件是否比后面的文件旧,是则返回真
-ef
判断前后两个文件的i节点是否相同,是则返回真
使用示例如下:
关于整数的判断,使用的方式如下:
-eq
判断前后两个整数是否相等,是则返回真
-ne
判断前后两个整数是否不相等,不相等则返回真
-gt
判断前一个整数是否大于后一个整数,是则返回真
-lt
判断前一个整数是否小于后一个整数,是则返回真
-ge
判断前一个整数是否大于等于后一个整数,是则返回真
-le
判断前一个整数是否小于等于后一个整数,是则返回真
关于字符串的判断,使用方式如下:
-z
判断后面的字符串是否为空,是则返回真
-n
判断后面的字符串是否不为空,不为空则返回真
==
判断前后字符串是否相等,相等则返回真
!=
判断前后两个字符串是否不相等,不相等则返回真
>
前面字符串的ascii码是否大于后面字符串的ascii码,大于则返回真
<
前面字符串的ascii码是否小于后面字符串的ascii码,小于则返回真
=~
左侧的字符串是否能够被右侧的pattern所匹配,是则返回真
流程控制
if语句控制流程,内容如下:
多分支case语句控制流程,内容如下:
for循环控制流程,内容如下:
while循环控制流程,只要条件为真,便一直执行下去。内容如下:
until循环控制流程,一直执行,直到条件为真为止。内容如下:
参考链接
linux之shell脚本
wiki百科: Unix shell