前言
shell 脚本说难也难说不难找起 bug 来确实费劲,是什么导致 shell 语法规则很大众化,但是让我们去找程序的错误却这么费劲呢?这是因为 shell 其实是一个不断增增补补的语言,很多规则都是之前不断“补丁”上去的,导致让人感觉很混乱,特别是这个括号匹配,弄的非常的反人类,如果不是经常使用是很难去记忆的。
单小括号 ()
正则表达式中使用
(aa)|(bb)
用于做某个输出命令,配合$
使用
# 这个可以拿到 test.log 的文本
$(cat test.log)
用于数组初始化操作
local arr=(1 2 3 4);
双小括号 (())
表示其中进行数字类型的计算(而且只支持整型),双小括号中还支持布尔值判定,并且当被双小括号框中,整体就应该被看成一个变量。其实这里双小括号里头就是支持 C 语言语法规则,可以不加美元符,可以再加单小括号把一些运算先括起来等
# 默认 a 是字符串类型
a=1;
# 把 a 看成数字,改变前面定义的变量时,必须要加双小括号,或者用 let 语句,否则会把其视为字符串类型
((a++));
let "a++";
# 输出,双小括号应该被看成一个变量
echo $((a+1));
做算术运算符比较时,双小括号表示其中可以使用 C 语言风格,其中变量不用加美元符等
# 这里下面哪里加空格都不影响
a=1;
# if 中判断比较时候的双小括号,其中可以使用 C 语言风格
if((a==1))
then
echo "right";
else
echo "error";
fi;
# for 中算数运算,也完全可以使用 C 语言的形式,如下
for((i=0;i<5;i++))
do
echo "$i";
done;
# while 中算数运算判断布尔,也同样
while((a==1))
do
echo "$a";
done;
单中括号 []
[ 本来表示一个比较的命令,注意空格
比较的话==
和!=
只支持字符串比较,-eq
,-gt
,-lt
>
<
支持数字类型比较,但是但括号中可不能使用 &&
这类的符号哦,想使用就得使用更加扩展的 [[]]
了
# 其实 [ 本来就是 shell 中的一个命令表示 test 测试布尔值,这也是中括号后为什么要空格的原因。shell 中云算符只支持字符串比较,但是 -eq -gt -lt > < 这些可以支持数字比较
a=1;
# 这里写 a -eq 1 也是成立的
if [ a==1 ]
then
echo "right";
else
echo "error";
fi;
正则表达式表示中括号中匹配任意一个
# 能匹配其中任一个就表示匹配成功
[123]
数组固定形式,与其他程序一样
a[0]=1;
printf "${a[0]}";
双中括号 [[]]
在 [] 上的扩展,支持了通配符甚至是正则匹配和 && 等符号,但是模式必须在右边
注意这个双中扩后也要有空格!通常这个 [[]]
比 []
更加实用
a=1;
# 支持 && ||,以往但括号中是不支持的
if [[ $a==1&&$a!=2 ]]
# 支持通配符的匹配
if [[ $a==* ]]
# 支持正则,必须要加 =~
if [[ $a=~\d ]]
大括号 {}
对数组的引用
a[0]=1;
echo "${a[0]}";
正则表达式表示前一个字符出连续出现几次
{2,}
通配符表示文件切割
# 会创建 test1.sh 和 test2.sh
touch {test1,test2}.sh
# 会创建 test1.sh test2.sh test3.sh test4.sh 这四个文件
touch {test{1..3},test4}.sh
touch {test[1-3],test4}.sh
表达式符号 ``
抱歉,由于我确实不知道这个符号叫什么名字,目前用表达式符号来代替这个符号的名字
用于写一个可输出的表达式,常用于输出布尔值检测条件
if `$a -eq $b`
shell 编写规范
这个编写规范算是我个人的一个小总结,以后遇到各种情况统一按照如下规范处理,这样我们就不容易写错 shell 脚本了!有点类似 alibaba 编码规范,但应该不同,这个是我个人总结的心得,哈哈
# 规范一:shell 尽量模仿 c 语言句尾加分号的方式,该加的就加,减少思维负担
echo "right";
# 规范二:尽量模仿 c 语言编写方式,不应该多加空格,能不加就最好不要加
if($a==1)
# 规范三:所有的 let 和 echo printf 能加双引号必须得加
echo "haha";
printf "haha";
let "a++";
# 规范四:shell 中不管是条件语句还是循环语句建议首先使用 (()) 来进行逻辑判定,而不应该先去考虑 [] 和 [[]],因为 (()) 中表达式的写法也是与 c 语言一致,减少思维负担与记忆负担
if((a==1))
while((a==1))
for((i=0;i<5;i++))
# 规范五:如果想要通过通配符或者正则更灵活的判定条件的时候,我们才考虑换走 (()) 而使用 [[]]
if [[ $a=~\d{2,3} ]]
# 规范六:for 循环的编写方式我们建议首先考虑的是如下:
for((i=0;i<5;i++))
# 规范七:能用 let 就不要使用 (()) 来表示原数字类型计算
a=1;
let "a++";