${1+"$@"}是什么意思 (What does ${1+"$@"} mean)?

2770阅读 0评论2016-02-02 芸锺鹤
分类:LINUX

摘自:http://blog.163.com/nkty_coolnick/blog/static/58871698201521603038981/

      最近发现网上有不少人问${1+"$@"}是什么意思,希望这篇文章能很彻底的回答这个问题。

      首先,我想绝大多数人明白“参数展开”的概念。比如${variable},在脚本执行的时候,会自动替换成变量的值。例如下面的例子,
会将"Hello world!"输出,而不是"$message"。

      $message="Hello world!"

      echo $message

      这里用大括号{}将变量名括起来,目的防止变量之后紧跟着的字符被解释成变量名的一部分。例如下面的例子,必须用{}将message
括起来,否则message_会被解释成变量名。

      $message="Hello world!"

      echo ${message}_


上面只是参数展开最基本的应用,而实际使用中,在{}里面可以加入各种运算符,就是运算符展开了。下面是几种典型的运算符展开方式。
#NOTE: 下述语法中,经常会看到varname为1,即表示$1

1) ${varname:-word}

    如果varname存在且非null, 则返回其值否则返回word。主要用于在给变量定义默认值的场景。例如如果count未定义,则${count:-0}
    的值为0。若vaname为1,也就是调用时的第一个参数,也就是说若调用时携带参数则使用该参数,未携带参数则使用后者作为默认值。

2) ${varname:+word}

    如果varname存在且非null, 则word否则,返回null。例如如果count已定义,则${count:+1}返回1。

3) ${varname:=word}

    如果varname存在且非null, 则返回其值否则设置它为word,并返回其值。主要用于给变量设置默认值的场景。例如如果count未定义,则
    ${count:=0}则设置count为0。这里要注意和1)的区别,在1)中,并不会改变count的值。注意:此语句若varname为1,则会输出警告信息
  因为shell不允许对位置参数($1)直接赋值。

4)${varname:?message}

    如果varname存在且非null, 则返回其值否则显示varname: message,并退出当前的脚本。省略message,则显示默认信息parameter
   null or not set。例如如果count未定义,则$count:?"undefined!"}将显示count:undefined!。



注意,每个运算符里面的冒号都是可选的。所以4)正好回答了本文标题的问题。${1+"$@"}意思是如果第一个参数$1定义了,则返回"$@",
        否则返回null
。$@是传递给当前脚本的命令行参数,置于双引号内,会展开为个别的参数。我相信看到这里,大部分人心里会有两点疑问:

     

      1、为什么要将$@置于双引号内?

      2、${1+"$@"}到底有什么用,为什么不能直接用"$@"?


      首先来解释第一个问题。假如有如下脚本test.sh,

#!/bin/sh

echo "Begin to invoke JAVA program..."

......

$JAVA $JAVA_OPTS  com.test.projectA.moduleA.TestMain  $@

      而当你这样调用这个脚本:

sh  test.sh  10  'Hello world'

      你期望传给TestMain的是两个参数,而实际上TestMain收到了3个参数,分别是:10,'Hello, world'。这就是为什么要将$@置于双引号
内的原因。这样我们就回答了第一个问题。


再来看第二个问题。假如有下面的脚本,

	$ cat args.sh
	for i in "$@"; do
	    echo arg: \"$i\"
	done

如果你至少提供了一个参数,那么你能得到预期的输出,例如,

	$ sh args.sh 1 2
	arg: "1"
	arg: "2"

然后,如果你没有提供任何参数,你期望没有任何输出,而实际你仍然能得到一个空输出,例如,

	$ sh args.sh
	arg: "" 

这就是为什么要用${1+"$@"},而不直接用"$@"的原因。

本文到此回答了所有问题。

上一篇:Openwrt squafs文件系统及sysupgrade升级探究
下一篇:Openwrt ubus机制的探究