shell编程

总结一下shell编程的语法规则以及注意事项。

  • 定义变量时,不使用$,等号两边不能有空格,使用变量时使用$
例如:
val='abc'   (正确)
val = 'abc' (错误) 
echo ${val} (使用变量)
  • 字符串:
获取字符串长度:${#abc},结果返回3;截取字符串:${abc:1:2}。
例如:
str='abcdefg'
echo ${str:1:2}

结果返回:bc;意思是重二个字符开始,截取两个字符;这里是重0开始计算的。

  • 数组:
定义数组:arr=(val1 val2 val3 ... valn) 或 arr[0]=val0
使用数组元素:${arr[0]}  
输出数组元素:${arr[*]} 或 ${arr[@]}  
获取数组长度:${#arr[*]} 或 ${#arr[@]}
  • 运算符

计算数值时使用:expr 表达式$((表达式)),如果使用 expr 时,乘法使用 \*,使用运算符时,使用[],并且运算符两边都要有空格,例如:if [ $a -eq $b ] then fi

关系运算符
-eq 检测两个数是都相等,相等返回 true  
-ne 检测两个数是都相等,不相等返回true  
-gt 大于号  
-lt 小于号  
-ge 大于等于
-le 小于等于
布尔运算符
!  非  
-o 或  
-a 与
逻辑运算符
&& 逻辑的AND
|| 逻辑的OR

注意:使用逻辑运算符时,if语句需要使用[[ 表达式 ]]

例如:
a=10
b=10
if [[ $a -lt 100 && $b -gt 100 ]]
then
	echo "返回 true"
else
	echo "返回 false"
fi
字符串运算符
=   检测两个字符串是否相等,相等返回true    例:[ ``a = ``b ]  
!=  检测两个字符串是否相等,不相等返回true  例:[ ``a != ``b ]  
-z  检测字符串长度是否为0,为0返回true   例:[ -z $a ]  
-n  检测字符串长度是否为0,不为0返回true    例:[ -n $a ]  
str 检测字符串是否为空,不为空返回true      例:[ $a ]  
文件测试运算符

$file 为文件路径

[ -b $file ] 检测文件是否是块设备文件,是返回true  
[ -c $file ] 检测文件是否是字符设备文件,如果是,则返回 true  
[ -d $file ] 检测文件是否是目录,如果是,则返回 true  
[ -f $file ] 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true  
[ -g $file ] 检测文件是否设置了 SGID 位,如果是,则返回 true  
[ -k $file ] 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true  
[ -p $file ] 检测文件是否是有名管道,如果是,则返回 true  
[ -u $file ] 检测文件是否设置了 SUID 位,如果是,则返回 true  
[ -r $file ] 检测文件是否可读,如果是,则返回 true  
[ -w $file ] 检测文件是否可写,如果是,则返回 true  
[ -x $file ] 检测文件是否可执行,如果是,则返回 true  
[ -s $file ] 检测文件是否为空(文件大小是否大于0),不为空返回 true
[ -e $file ] 检测文件(包括目录)是否存在,如果是,则返回 true
  • test命令
    []作为基本运算符使用时,内部不能有空格
例如:  
a=5
b=5
res=$[a+b]
echo $res # 结果为10
  • read
    read 等待用户输入。
例:
#!/bin/sh
read name
echo "输入的值name等于 ${name}"
  • 流程控制
if语句:
if condition
then
	command
fi
写成一行:if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi

if else:
if condition
then
	command1
else
	command2
fi

if else-if else:
if condition1
then
	command1
elif condition2
then
	command2
else
	command3
fi
for循环
for var in item1 item2 ... itemN
do
	command1
	...
	commandN
done

写成一行:for var in item1 ... itemN; do cmooand1;command2... done;
while循环,与until循环用法相同(结果为真时退出循环)
例:
#!/bin/sh
int=1
while(( $int<=5 ))
do
	echo $int
	let "int++"
done

使用了 let 命令,用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量。

case
例:
read aNum
case $aNum in
	1) echo '1'
	;;  # 两个;表示break,跳出
	2|3) echo '2'
	;;
	*) echo 'none'
		break # 跳出所有循环,continue跳出当前循环
	;;
esac
  • 函数
定义函数
[function] funcName[()]{
	command
	[return n] # n为0-255之间的数字
}

funcName  # 调用函数funcName

1.可以带function fun()定义,也可以直接fun()定义,不到任何参数
2.参数返回,可以显示的加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。

例:
#!/bin/sh
function funcName(){
	echo 'this is a function!'
}
# 开始执行函数
funcName
# 函数执行结束
函数参数
例:
funWithParam(){
	echo "第一个参数:$1"
	echo "第二个参数:$2"
	echo "第五个参数:${5}"
	echo "参数总个数:$#"
	echo "作为字符串输出所有参数:$* !"
}
funWidthParam 1 2 3 4 5 6 7  #调用函数传参

备注:$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数;
$$ 脚本运行的当前进程ID号;
$! 后台运行的最优一个进程的ID号
$@$*相同,但是使用时加引号,并在引号中返回每个参数;
$- 显示Shell使用的当前选项,与set命令功能相同
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

  • Shell文件包含
    Shell包含外部脚本语法合适如下:
. filename    # 注意点号(.)和文件名中间有一个空格
或
source filename

**注:**被包含的文件不需要可执行权限