使用动态数组名称来检索值

使用动态数组名称来检索值

我试图在 for 循环中检索一个值,但尽一切努力都失败了。在此脚本中,我必须声明 SSHFS 挂载脚本的远程路径。在下面的代码中,我将路径存储在 user[remote] 数组中。在脚本的更下方,该用户被保存在 $left 中。所以air[remote]将是$left[remote]。但是,我不知道该怎么做。我最近的努力${!left[remote]}没有导致任何错误,只是导致空值。

如何使用 $left[remote] 动态获取远程路径值?

#!/bin/bash

declare -A air
air[remote]="/home/air"

declare -A bhm
bhm[remote]="/home/bhm"

declare -A schwimserver3
schwimserver3[remote]="/var/www/clients/client1/web7/home/schwimserver3"


#echo ${air[remote]}

for u in $HOME/Remote/SSHFS/*
do
  if [ -d $u ]; then
    basename "$u" >/dev/null
    acct="$(basename -- $u)"
    
    IFS=- read -r left right <<< "$acct"
    if mountpoint "${HOME}/Remote/SSHFS/${acct}" >/dev/null; then
        printf '%b\n' "unmount ${right},fusermount -u /home/schwim/Remote/SSHFS/${right}"
    else
        printf '%b\n' "mount ${right},sshfs -o workaround=rename $left@$right:${!left[remote]} /home/schwim/Remote/SSHFS/${acct}"
    fi

  fi
done

谢谢你的时间!

答案1

问题是,您需要双重解释该数组。如果 left="air",则 $left[remote] 不等于air[remote]
要执行双重替换,您需要首先解释$leftinto air,然后air[remote]像这样解释:
$ air[remote]="/home/air" $ left="air" ; For clarity, lets make a temporary variable with the first substitution $ name_var='${'$left'[remote]}' ; Lets see the value of name_var $ echo $name_var ${air[remote]} ; Now, we need to force the shell to interpret this value $ eval echo $name_var /home/air ; Or, to store this in a value resolved_value=$( eval echo $name_var )
或者,作为单行:
resolved_value=$( eval echo '${'$left'[remote]}' )

这是如何工作的:
技巧在于创建 $name_var:
'${' (带单引号,而不是双引号)表示按原样使用字符(即不将它们解释为名为{
$left 的变量,然后将替换为它的变量) value "air"
'[remote]}' 将按原样使用这些字符(同样,单引号,而不是双引号),然后
命令eval将这些字符(或变量 $name_var 的内容)替换到解释器中并处理其结果。那么就是变量 ${air[remote]}" 的值

在代码中,您可以构建 $resolved_value 变量并将其放入脚本中:
printf '%b\n' "mount ${right},sshfs -o workaround=rename $left@$right:${resolved_value} /home/schwim/Remote/SSHFS/${acct}"

或者插入整个表达式:
printf '%b\n' "mount ${right},sshfs -o workaround=rename $left@$right:$( eval echo '${'$left'[remote]}' ) /home/schwim/Remote/SSHFS/${acct}"

尽管第一个选项的可读性更好。

答案2

为什么不反转数组:

declare -A remotes=(
    [air]="/home/air"
    [bhm]="/home/bhm"
    [imserver3]="/var/www/clients/client1/web7/home/schwimserver3"
)

那你就用"${remotes[$left]}".

这就是关联数组如此有用的原因:您不必使用动态变量名称。


要使用动态名称,请使用 bash 版本 4.3+ 并使用 namerefs:

declare -A foo=( [bar]=baz )
left=foo
declare -n ref=$left
echo "${ref[bar]}"

参考。3.4 外壳参数在手册中

相关内容