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 쉘 매개변수설명서에