Shell Scripts
Shell 编程笔记
基本语法模块
指定脚本解析器
#!/bin/bash
#!/bin/sh
bash
是最常用的解析器,sh
等其他 shell 解析器与 bash 有语法上的区别
变量
-
变量名:字母、数字、下划线,数字不可开头
-
变量赋值:
user="festu" user=festu"festu" # festufestu user = festu # 赋值失败
字符串常量可以不带双引号,连接字符串不用
+
(会被识别为字符串内容) -
变量引用:
echo $user echo ${user} echo "$user" echo "${user}" # 推荐
双引号包裹可以避免很多奇怪的错误,例如它会解析变量中的换行与换行符。
普通数组
arr=(A B "C" D)
echo ${arr[0]} # A
关联数组
declare -A rel_arr=(
["name"]="festu"
["gender"]="Male"
)
-
@, *
可以获取数组中的所有元素echo ${arr[@]} echo ${arr[*]}
-
${#arr[@]}
获取数组长度 -
${arr:2:3}
截取数组元素,从下标2
开始截取 3 个
特殊变量
$0:执行文件名
$1:传入的参数1
$#:参数个数
$*:"$*" == “$1 $2...”
$@:"$1" "$2" "$3"...
$$:脚本进程号
$?:最后命令的退出状态
语句
条件-IF
if [ $a >= $b ]; then
echo "a is biiger"
elif [ $a != $b ]; then
echo "a is smaller"
else
echo "a and b is equal"
fi
条件-Case
read -p "Hello! Input your optoins:" opt
case $opt in
Y|y)
#....
;;
N|n)
#...
;;
<pattern>)
#...
;;
*)
#...
;;
esac
- 第一行语句从标准输入读取内容,传递给
opt
变量。 <pattern>
支持解析正则表达式,无需引号包裹。*)
表示default
;;
表示break
循环-For
# 也支持 i+=1
for ((i=1;i<=100;i++))
do
echo $i
done
特殊符号
-
$(),``,${}
会返回内部命令/语句的输出:echo `echo 123` # 123
-
$<str>
获取变量内容$[]
获取算数表达式的结果:a=$[ 1+2 ] echo $a # 3
算术运算
支持数字运算
number=$()
+
-
*
/
%: 取余
=: 赋值
==: 相等
!=: 不相等
比较运算
方括号括起表示一个比较运算:
[ $a -eq $b ]
需要注意充足的空格,与其他语句耦合时也要有空格,如:
if [ $a -eq $b ];then
# do sth...
fi
数字(关系)
[ $a -gt $b ]
-eq:=
-ne:<> != ~=
-gt:>
-lt:<
-ge:>=
-le:<=
布尔
[ $a -lt 20 -o $b -gt 100 ]
!: 非
-o: 或运算
-a: 与运算
逻辑
[ -z $a ] && [ -z $b ]
&&
||
字符串
[ -z $a ]
[ $a = $b ]
[ $a ]
-z:长度是否为0
-n:长度是否不为0 | 参数是否不为空
=:是否相等
!=:是否不相等
$:是否不为空
文件
[ -b $file ]
-b:块设备
-c:字符设备
-d:目录
-f:普通文件
-g:有无设置SGID
-k:有无设置sticky
-p:有名管道
-u:有无设置SUID
-r:可读
-w:可写
-x:可执行
-s:为空
-e:是否存在
高级比较
高级表达式也有空格要求
[[]]
支持字符串的高级表达式(有些 shell 不支持):
[[ $fileName == test* ]]
[[ $fileName != test* ]]
# 需要在比较运算符两侧添加适当的空格来获得正确的结果
(())
支持高级数学表达式:
(( $a-$b++ >= $c<<2 ))
var++
var--
++var
--var
!
~: 按位求反
**: 幂
<<
>>
&
|
&&
||
多文件编程
# 加载其他 shell 脚本
source other.sh
. other.sh
- 在交互式 shell 中加载会更新环境变量中的变量与函数。
.
的效果和source
一样,用于加载 shell 脚本。