shell脚本编程
本质上是shell命令的有序集合, 将shell命令按照一定的逻辑顺序实现指定功能,放到一个文件中文件叫脚本文件,后缀.sh,可以直接执行,不用编译。
写一个shell脚本文件步骤:
创建一个脚本文件
touch xxx.sh
将脚本文件权限修改为可执行
chmod 777 xxx.sh
编辑脚本内容
vi xxx.sh
执行脚本文件
./xxx.sh 或者 bash xxx.sh
shell变量
shell中允许建立变量存储数据,但是不支持数据类型,(如:整型、字符、浮点类型),所有赋值给变量的值都解释为一串字符。
变量的定义格式:
val=10 #这里的等号两边绝对不能有空格!!
取shell变量的值:$变量名
$val
shell变量的分类
环境变量 printenv 或 env
HOME=/home/hq
用户自定义变量
在shell编程中通常定义的变量名用大写,变量的调用:$变量名
Y=yy
X=$Y
echo $X //输出yy
使用unset命令删除变量的赋值
X=xx
unset X
echo $X //没有任何输出
位置变量或命令行参数
$0 # 执行的脚本名
$1-$9、${10}-${n} # 命令行空格传的参数
$# # 命令行参数个数,除$0
$@ $* # 遍历输出命令行参数内容
预定义变量
$? 获取的是上一句命令是否正确执行的结果
shell中:0:真 非0:为假
$$ 获取进程pid
shell命令
read命令(类似c中scanf)
从终端获取值赋值给变量
read 变量名1 变量名2
expr命令
主要用于进行简单的整数运算,包括加(+)、减(-)、乘(*)、整除(/)和求模(%)等操作
expr \( 12 + 3 \) \* 2
NUM=`expr 12 + 3` #将运算的结果赋值给变量
注意:
运算符左右两侧必须有空格
*和()必须加转义字符,* 、 ( )
expr语句可以直接输出运算结果
let命令
运算结果需要赋给一个变量,变量参与运算的过程不用加$取值
let r=(1+3)*2
let r+=1 # r++
test命令
test语句可测试三种对象:字符串、整数、文件属性
字符串的测试:(等号两边加空格)
s1 = s2 # 测试两个字符串的内容是否完全一样
真,假
echo $?
s1 != s2 # 测试两个字符串的内容是否有差异
-z s1 # 测试s1 字符串的长度是否为0
-n s1 # 测试s1 字符串的长度是否不为0
整数的测试:
a -eq b # 测试a与b是否相等(equal)
a -ne b # 测试a与b是否不相等(unequal)
a -gt b # 测试a是否大于b
a -ge b # 测试a 是否大于等于b
a -lt b # 测试a 是否小于b
a -le b # 测试a 是否小于等于b
文件属性的测试:
-d name # 测试name 是否为一个目录
-f name # 测试name 是否为普通文件
-e name # 测试文件是否存在
shell语句逻辑
说明性语句
#! /bin/bash
#告诉操作系统使用哪种类型的shell执行此脚本文件
条件语句
if…then…fi 语句
# 基本结构
if 表达式
then
命令表
fi
#如果表达式为真, 则执行命令表中的命令; 否则退出if语句, 即执行fi后面的语句。
if和fi是条件语句的语句括号,必须成对使用;命令表中的命令可以是一条, 也可以是若干条。
if…then…else…fi 语句
# 分层结构1
if 表达式
then
命令表1
else
命令表2
fi
if…then…elif…then…else…fi 语句
if 表达式1
then
命令表1
elif 表达式2
then
命令表2
elif 表达式3
then
命令表3
else
命令表4
上述三种格式可以进行互相嵌套
eg. shell脚本实现冒泡排序
#!/bin/bash
arr=(53 100 86 92 86 55 65 76 56 59)
#冒泡排序
for ((i=0;i<${#arr[*]};i++))
do
for ((j=i+1;j<${#arr[@]};j++))
do
if [[ ${arr[i]} -gt ${arr[j]} ]] ; then
max=${arr[i]}
arr[i]=${arr[j]}
arr[j]=$max
fi
done
done
echo ${arr[*]}
read -p "请输入成绩:" sum
for ((i=0;i<${#arr[*]};i++))
do
if [[ ${arr[i]} -gt $sum ]] ; then
tmp=$i
break
fi
done
for ((j=${#arr[*]};j>i;j--))
do
arr[j]=${arr[j-1]}
done
arr[i]=$sum
echo ${arr[*]}
分支语句
case…esac语句
case 字符串变量 in
模式1)
命令表1
;;(相当于C语言中的break)
模式2)
命令表2
;;
……
*)
命令表n
;;
esac
注意:
case语句只能检测字符串变量
命令表以单独的双分号行结束,退出case语句
模式n常写为字符,*表示所有其它模式
case匹配项中可以存在多个模式,每种模式之间用|隔开
逻辑运算的书写格式:
|| :逻辑或
[ 表达式1 ] || [ 表达式2 ]
[ 表达式1 -o 表达式2 ]
&& :逻辑与
[ 表达式1 ] && [ 表达式2 ]
[ 表达式1 -a 表达式2 ]
! :逻辑非
[ ! 表达式 ]
循环语句
for..do..done
for 变量名 in 单词表
do
命令表
done
for I in 1 3 5 7 9
for I in `seq 1 2 10` # 1为起点,步长为2,10为终点
# 上述两句等价
for i in {…} do...done (大括号和数字之间不加空格)
for i in {1..10} do...done: # 1为起点, 10为终点
for ((i = 0; i < N; i++)) do...done (最常用)
#! /bin/bash
#输出1到100的和
num=0
for ((i = 0; i < 101; i++))
do
let num+=i
done
echo $num
循环控制语句
while..do..done
while 命令或表达式
do
命令表
done
#while语句首先测试其后的命令或表达式的值,如果为真,就执行一次;然后再测试该命令或表达式的值,执行循环体,直到该命令或表达式为假时退出循环。
#! /bin/bash
#输出1到100的和
num=0
I=0
while [ $I -le 100 ]
do
let num+=I
let I+=1
done
echo $num