做为运维人员,经常使用linux的都知道,在linux下面,很多命令、关键字,看起来长的很像,但实际应用起来就能够发现有时候还是有区别的,当然不仔细的人或许你是永远也不会明白,到底什么时候该使什么招。今天做为菜鸟的我,就给大家简单的分享几个,不全之处,希望大家留言指出,本博主随时更新,以方便大家紧急查阅。
菜鸟的发现:
一、$vra_name与"$var_name"
二、"$*"与"[email protected]"
三、[ ]与[[ ]]
一、$vra_name与"$var_name"
大多数情况下,$vra_name与"$var_name"没什么区别,但是就因如此,所以我们写脚本的时候,经常会遇到一些另人费解的报错,很多人就感觉我写的没错啊,语法没错,命令拼写也没有问题,就不知道究竟错在哪里。殊不知就是这个引号让你绞尽脑汁,如果你能看到我这个小菜鸟的博文,或许你也彻底明白并记住它了。
接下来,我们用一个简短的示例演示一下
[[email protected] test]# cat test.sh 展示测试环境
#!/bin/bash
#Author:wangjun
#Version:1.0
#Create time:2016-08-14 21:07:38
#Description:
if [ $1 = start ];then 这脚本咋一看,相当简单,语法、拼写各方面也都没问题吧
echo start
elif [ $1 = stop ];then 好的,接下来,就让我们带上参数来亲测一下
echo stop
elif [ $1 = restart ];then
echo restart
else
echo "Unknown parameter"
fi
[[email protected] test]# test.sh start 带上正确的参数一点问题也没有
start
[[email protected] test]# test.sh rest
Unknown parameter
[[email protected] test]# test.sh 可为什么没带参数,就报了一大串的错误了,没带参数,不也是属于else分支吗
./test.sh: line 8: [: =: unary operator expected
./test.sh: line 10: [: =: unary operator expected
./test.sh: line 12: [: =: unary operator expected
Unknown parameter
[[email protected] test]#
仔细看看,前三个判断的分支都报错了,错误提示大概意思是期待一元表达式,那我们就要思考一下,接下来,我们给$1包上一个引号再来看看
[[email protected] test]# vim test.sh
[[email protected] test]# cat test.sh
#!/bin/bash
#Author:wangjun
#Version:1.0
#Create time:2016-08-14 21:07:38
#Description:
if [ "$1" = start ];then
echo start
elif [ "$1" = stop ];then
echo stop
elif [ "$1" = restart ];then
echo restart
else
echo "Unknown parameter"
fi
[[email protected] test]# test.sh stop
stop
[[email protected] test]# test.sh restart
restart
[[email protected] test]# test.sh hello
Unknown parameter
[[email protected] test]# test.sh 头痛的问题消失了,即使不带参数,也不会报错,正常走到了else分支
Unknown parameter
[[email protected] test]#
这回应该能够明白这个大多数情况都一样的$vra_name与"$var_name"之间一个引号的威力了吧。所以小菜还是建议大家养成一个良好的编程习惯,不惯它俩大多数情况是不是效果等同,我们不要去偷那个懒,只要是引用变量的时候,我们就把那个该死的引号给带上不就得了。免得头痛了还不知何故。
二、"$*"与"[email protected]"
接下来我们就再来一个也和这个引号有一点关系的"$*"与"[email protected]",写过脚本的都知道,脚本里面涉及到了位置变量,$*与[email protected]都表示变量列表,可谁知道用小菜建议的以不变应万变的规律这回就掉大了。
测试环境:
[[email protected] test]# cat script1.sh 测试环境展示("$var-name")
#!/bin/bash
#Author:wangjun
#Version:1.0
#Create time:2016-08-14 15:18:57
#Description:
script2.sh "$*" 特殊变量(参数列表)加引号调用的
echo ==============================
script2.sh "[email protected]" 特殊变量(参数列表)加引号调用的
[[email protected] test]# cat script2.sh
#!/bin/bash
#Author:wangjun
#Version:1.0
#Create time:2016-08-14 15:12:52
#Description:
echo "The first parameter is:$1"
echo "The second parameter is:$2"
echo "The third parameter is:$3"
echo "All parameters is:[email protected]"
[[email protected] test]# script1.sh a ab abc $*和[email protected]用引号时的执行效果
The first parameter is:a ab abc
The second parameter is: "$*"表示的是把整个列表当成一个参数$1
The third parameter is: 所以$2和$3都为空值
All parameters is:a ab abc
==============================
The first parameter is:a
The second parameter is:ab "[email protected]"表示的还是分散的整个列表
The third parameter is:abc 所以$2和$3都能正常得到赋值
All parameters is:a ab abc
[[email protected] test]#
正常加了引号,这回也掉大了,两个都是表示参数列表的变量,调用的同样参数还有区别了,仔细查阅相关资料,终于发现$*和[email protected]确实是双胞胎,但它们还是有区别的:
"$*"(用双引号时): 传递给脚本的所有参数,全部参数合为一个字符串
"[email protected]"(用双引号时): 传递给脚本的所有参数,每个参数为独立字符串
接下来我们看一下不用引号时的示例:
[[email protected] test]# cat script1.sh 测试环境展示($var-name不用引号)
#!/bin/bash
#Author:wangjun
#Version:1.0
#Create time:2016-08-14 15:18:57
#Description:
script2.sh $*
echo ==============================
script2.sh [email protected]
[[email protected] test]# cat script2.sh
#!/bin/bash
#Author:wangjun
#Version:1.0
#Create time:2016-08-14 15:12:52
#Description:
echo "The first parameter is:$1"
echo "The second parameter is:$2"
echo "The third parameter is:$3"
echo "All parameters is:[email protected]"
[[email protected] test]# script1.sh a ab abc $*和[email protected]不用引号时的执行效果
The first parameter is:a
The second parameter is:ab 因为$*和[email protected]不用引号时,两个表示的都是分散的整个列表
The third parameter is:abc 所以$2和$3都能正常得到赋值
All parameters is:a ab abc
==============================
The first parameter is:a
The second parameter is:ab
The third parameter is:abc
All parameters is:a ab abc
[[email protected] test]#
$*和[email protected]不用引号时:两个表示的都是分散的整个列表(也即每个参数都是独立的字符串),能看得出来,这次没用引号反而还不会出岔子。所以只能得出一个结论,任何事务都不是绝对的,一定是有前提或环境的。当然对于我们使用linux系统的运维人员来说,这些知识你是必须掌握的,否则出了这些情况你真会抓狂的。
三、[ ]与[[ ]]
大多数情况下,[ ]与[[ ]]也都差不多,那么今天小菜再你来看一幅伤脑筋的画卷
[[email protected] test]# A=good
[[email protected] test]# echo $A
good
[[email protected] test]# [ -n $A ] && echo "A is nonespace" || echo "A is space"
A is nonespace 测试字符串是否非空,没加引号调用变量,也没报错
[[email protected] test]# [ -z $A ] && echo "A is space" || echo "A is nonespace"
A is nonespace 走运了(这是属于大多数情况之列的)
[[email protected] test]# [ $A =~ go ] && echo "Matching" || echo "Not matching"
-bash: [: =~: binary operator expected 再来一个用右边的模式去匹配左边,错误报告来了
Not matching
[[email protected] test]# [ "$A" =~ go ] && echo "Matching" || echo "Not matching"
-bash: [: =~: binary operator expected 使法宝——加一个引号,结果失效了
Not matching
[[email protected] test]# [[ "$A" =~ go ]] && echo "Matching" || echo "Not matching"
Matching 双中括号的大救星从天而降,妖怪终于压到了五指山下
[[email protected] test]# [[ $A =~ god ]] && echo "Matching" || echo "Not matching"
Not matching 此时发现摘掉它的紧箍咒——双引号,它也无力翻身
[[email protected] test]# [[ $A =~ go ]] && echo "Matching" || echo "Not matching"
Matching
[[email protected] test]#
通过这一次的测试我们又可以发现,[ ]与[[ ]]也是孪生兄弟,但有时候它们的性格也还是有点小区别的,所以我们在用的时候,同样需要把好关了。
好的,今天的分享也就至此为此,不全之处,希望读者及时留言补充。