動的配列名を使用して値を取得する

動的配列名を使用して値を取得する

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 シェルパラメータマニュアルに

関連情報