在bash中对$ @感到困惑

时间:2015-12-03 08:12:31

标签: bash

首先,一个简单的情况,直接在for循环中回显"$@"

#!/bin/bash
set -- "First one" "second" "third:one" "" "Fifth: :one"
IFS=:

# IFS=":", using "$@"
c=0
for i in "$@"
do echo "$((c+=1)): [$i]"
done

按预期输出:

1: [First one]
2: [second]
3: [third:one]
4: []
5: [Fifth: :one]

但是,当我将"$@"分配给变量var,然后在for循环中回显$var时,事情就变得复杂了:

#!/bin/bash
set -- "First one" "second" "third:one" "" "Fifth: :one"
IFS=:

# IFS=":", using $var (var="$@")
var="$@"
c=0
for i in $var
do echo "$((c+=1)): [$i]"
done

打印:

1: [First one second third]
2: [one  Fifth]
3: [ ]
4: [one]

为什么输出会改变?当我在for循环中添加var="$@"然后回显$var时,有人能告诉我发生了什么吗?

2 个答案:

答案 0 :(得分:2)

来自:What are the special dollar sign shell variables?

" $ @"是一个类似于数组的所有位置参数构造,{$ 1,$ 2,$ 3 ...}

答案 1 :(得分:1)

通常,在运行脚本时,命令行中提供的参数(称为位置参数)在脚本中可用作"$1""$2"等。 。位置参数列表包含在特殊的shell变量$@中(以及$*中)。 $@的特殊属性是在引用时(例如"$@"),它将保持位置参数的引用关系。 (例如,如果参数为"First one"$@将其保持为单个参数而不是两个<)

但是,还有一种使用set -- var1 var2 var3等在shell脚本中设置位置参数的方法。

IFS是控制分词的内部字段分隔符。 (这就是将字符串拆分为单词的方式 - 默认值:space tab newline)更改IFS=:会导致在':'字符上进行分词,而不是默认字符。

因此,在您的情况下,您设置了新的位置参数"First one" "second" "third:one" "" "Fifth: :one",如果您看看如果在每个':'字符处拆分它们将会中断,您会得到:

"First one second third"
"one  Fifth"
"  "
"one"

神秘解决了。这是一个很好的例子,教你如何定位位置参数和内部场分隔符及其对分词的影响。学习它 - 重要的是shell脚本。