Answers:
在比C更高级的任何级别中,指针(指向内存的位置)并不是一个有用的概念,无论它是Python还是Shell。对对象的引用在高级语言中当然有用,甚至可能对于构建复杂的数据结构也是必需的。但是在大多数情况下,根据内存地址进行思考的程度太低而无法使用。
在Bash(和其他shell)中,您可以使用${array[index]}表示法获取数组元素的值,使用为其分配值,并使用来获取数组中元素array[index]=...的数量${#array[@]}。方括号内的表达式是算术表达式。作为一个示例,我们可以为所有数组成员添加一个常量前缀:
for ((i=0 ; i < ${#array[@]} ; i++ )) ; do
array[i]="foo-${array[i]}"
done
(如果我们只关心值,而不关心索引,那for x in "${array[@]}" ; do...会很好。)
对于关联数组或稀疏数组,数字循环意义不大,但是我们需要使用来获取数组键/索引${!array[@]}。例如
declare -A assoc=([foo]="123" [bar]="456")
for i in "${!assoc[@]}" ; do
echo "${assoc[$i]}"
done
除此之外,Bash还可以通过两种方式间接指向另一个变量:
${!var}语法,它使用其变量的值的名字是在var,和declare内置名称创建(或ksh-compatible同义词,typeset)。declare -n ref=var使得ref到的变量的引用var。Namerefs还支持索引编制,因为如果有的arr=(a b c); declare -n ref=arr;话,${ref[1]}它将扩展为b。${!p[1]}相反,using 将p作为数组,并引用由其第二个元素命名的变量。
在Bash中,名称引用实际上是按名称引用,并且在函数内部使用名称引用将使用命名变量的局部值。这将打印local value of var。
#!/bin/bash
fun() {
local var="local value of var"
echo "$ref";
}
var="global var"
declare -n ref=var
fun
BashFAQ也有一篇关于间接的较长文章。
for foo in "${array[@]}" ; do ... done除非您需要将索引用于其他目的,否则for循环示例将更自然地编写。
不,bash没有“指针”,但是有引用:
$ spam="fred"
$ declare -n tripe=spam
$ echo $tripe
fred
$ tripe=juki
$ echo $spam
juki
从bash手册页:
可以使用-n选项
declare或local内置命令创建一个nameref或对另一个变量的引用,为该变量分配nameref属性。这允许变量被间接操纵。每当对nameref变量进行引用,分配,设置或修改其属性时(除了使用或更改nameref属性本身之外),实际上都会对nameref变量的值所指定的变量执行操作。在外壳函数中,通常使用nameref来引用变量,该变量的名称作为参数传递给该函数。例如,如果将变量名作为第一个参数传递给shell函数,则运行declare -n ref=$1函数内部将创建一个nameref变量ref,其值是作为第一个参数传递的变量名称。对ref的引用和赋值以及对其属性的更改被视为对名称作为$ 1传递的变量的引用,赋值和属性修改。如果for循环中的控制变量具有nameref属性,则单词列表可以是shell变量列表,并且将在执行循环时依次为列表中的每个单词建立名称引用。数组变量不能被赋予nameref属性。但是,nameref变量可以引用数组变量和下标数组变量。可以使用
unset内置的-n选项取消设置Nameref 。否则,如果unset如果以nameref变量的名称作为参数执行,则nameref变量引用的变量将不会设置。
不,shell不使用“指针”(如C所了解)。
数组可以使用索引:echo "${array[2]}"但是@在您的示例中,并不是真正的“指针”。这是表达“数组值列表”的一种方式。Shell解析器可以理解的内容。类似于以下方式:
$ echo "$@"
扩展到所有“位置参数”列表。
虽然bash整数索引数组可以像这样迭代地定义和访问;
declare -a obj
obj+=("val1")
obj+=("val2")
for item in ${obj[@]}; do
echo "${obj[${item}]} ${item}"
done
bash中基于关联或字符串的索引数组需要以下迭代定义;
declare -A obj
obj["key1"]="val1"
obj["key2"]="val2"
for item in ${!obj[@]}; do
echo "${obj[${item}]} ${item}"
done
回答有关指针和使用bash中的指针的问题;bash二进制编译器的内部功能确实确实利用了指向分配在堆栈上的内存的指针,并且确实通过使用eval。参见[间接参考] http://tldp.org/LDP/abs/html/ivr.html)
有龙;eval出于安全考虑,应谨慎使用