동적 배열 이름을 사용하여 값 검색

동적 배열 이름을 사용하여 값 검색

for 루프에서 값을 검색하려고 하는데 모든 노력이 실패합니다. 이 스크립트에서는 SSHFS 마운트 스크립트의 원격 경로를 선언해야 합니다. 아래 코드에서는 user[remote] 배열에 경로를 저장합니다. 스크립트 아래로 내려가면 사용자가 $left에 저장됩니다. 따라서 air[remote]는 $left[remote]가 됩니다. 그러나 어떻게 해야 할지 모르겠습니다. 최근 노력 ${!left[remote]}으로 인해 오류가 발생하지 않았으며 null 값만 발생했습니다.

$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]. 이중 대체를 수행하려면 먼저 다음과 같이 해석 한 다음 다음과 같이 해석
해야 합니다 . 또는 단일 행으로:$leftairair[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 쉘 매개변수설명서에

관련 정보