如何将关联数组传递给Gnu Parallel

时间:2019-03-23 17:27:37

标签: arrays bash parallel-processing associative-array gnu-parallel

就像标题一样,我声明了一堆变量和一个函数。当我通过一个函数传递它们时,我得到了期望的结果。但是通过并行运行相同的代码并没有...如何解决?

#!/bin/bash                                                

declare -xA MAP # export associative array                 
declare -x str="ing" # export variable                     
MAP[bar]="baz"                                             
MAP[bar2]="baz2"                                           


foo() {                                                    
  echo "$@"                                                
  echo "variable: ${str}"                                  
  echo "map: ${MAP[@]}"                                    
}                                                          

export -f foo                                              

foo "call function directly:"          

直接调用函数:
变量:ing
地图:baz2 baz

parallel foo ::: "call function through parallel" ::: 1 2 3

通过并行1调用函数
变量:ing
地图:
通过并行2调用函数
变量:ing
地图:
通过并行3调用函数
变量:ing
地图:

评论后编辑

看来这个问题的accepted answer是:实际上没有一种将数组变量编码到环境中的好方法。

有点难过...;)

1 个答案:

答案 0 :(得分:1)

从该问题下的评论看来,可接受的答案是:没有一种将数组变量编码到环境中的好方法。

仅此而已...;)

似乎还有另外一个:Accessing Associative Arrays in GNU Parallel,它的方法很复杂。但是...

经过一番修补(如Socovi建议可以解决特定问题),就我而言,看来足够好的解决方法是将临时文件中的数组“序列化”并在函数中反序列化。

#!/bin/bash                                                                   

declare -A MAP # export associative array                                    
declare -x str="ing" # export variable                                        
MAP[bar]="baz"                                                                
MAP[bar2]="baz2"                                                              
declare -x serialized_array=$(mktemp)   

# declare -p can be used to dump the definition 
# of a variable as shell code ready to be interpreted                                      
declare -p MAP > "${serialized_array}" 


# perform cleanup after finishing script                                      
cleanup() {                                                                   
  rm "${serialized_array}"                                                    
}                                                                             
trap cleanup EXIT                                                             


foo() {                                                                       
  echo "$@"                                                                   
  echo "variable: ${str}"                                                     
  source "${serialized_array}" # deserialize an array                         
  echo "map: ${MAP[@]}"                                                       
}                                                                             

export -f foo                                                                 

foo "call function directly:"  

直接调用函数:
变量:ing
地图:baz2 baz

parallel foo ::: "call function through parallel" ::: 1 2 3 

通过并行1调用函数
变量:ing
地图:baz2 baz
通过并行2调用函数
变量:ing
地图:baz2 baz
通过并行3调用函数
变量:ing
地图:baz2 baz