在Bash中,获取文件会影响文件中声明的关联数组。为什么?

时间:2018-11-18 17:40:32

标签: bash

测试用例如下:

sourced-file.sh

#!/bin/bash

declare -A MY_MAP=();

function C_function() {
  MY_MAP[foo]="bar";
}
  1. 第一次测试

test.sh

#!/bin/bash

function A_function() {
  source sourced-file.sh
  B_function;
  declare -p MY_MAP;
}    
function B_function() {
  C_function;
  declare -p MY_MAP;
}
A_function;

正在运行./test.sh打印:

declare -A MY_MAP=([foo]="bar" )
declare -A MY_MAP=([foo]="bar" )
  1. 第二次考试

test.sh

#!/bin/bash

function A_function() {
  source sourced-file.sh
  B_function;
  declare -p MY_MAP;
}    
function B_function() {
  source sourced-file.sh
  C_function;
  declare -p MY_MAP;
}
A_function;

运行./test.sh现在可以打印:

declare -A MY_MAP=([foo]="bar" )
declare -A MY_MAP=()
  1. 第三次考试

test.sh

#!/bin/bash

function A_function() {
  B_function;
  declare -p MY_MAP;
}    
function B_function() {
  source sourced-file.sh
  C_function;
  declare -p MY_MAP;
}
A_function;

运行./test.sh现在可以打印:

declare -A MY_MAP=([foo]="bar" )
./test.sh: line 5: declare: MY_MAP: not found

我正在使用bash 4.4.23,并且我想了解这种行为。有人可以阐明这一点吗?

2 个答案:

答案 0 :(得分:2)

  

在函数中使用时,declarelocal命令一样,将每个 name 设为本地,除非使用了-g选项。

当您在函数中source时,declare d个变量在该函数中是局部变量(在您从该函数调用的函数/子外壳中可见)。

演示:

a() { local x=10; echo "a before: $x"; b; echo "a after: $x"; }
b() { local x=20; echo "b before $x"; c; echo "b after: $x"; }
c() { echo "c before: $x"; x=30; echo "c after: $x"; }
x=5
a
echo $x

输出

a before: 10
b before 20
c before: 20
c after: 30
b after: 30
a after: 10
5

如果不进行测试,如果您在源文件中declare -gA MY_MAP,我希望您会有不同的结果。

答案 1 :(得分:2)

在没有-g的函数中使用时,declare声明一个local变量。从函数中获取declare的工作方式相同,即,它创建了一个局部变量。添加-g不会在情况2中清空该数组,而会在情况3中识别该数组。