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]
。二重置換を実行するには、まず次のように解釈し、次のように解釈する必要が
あります。または単一行として:$left
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 シェルパラメータマニュアルに