Bash에서 명명된 참조를 사용하여 연관 배열에 액세스할 수 없는 것 같습니다.

Bash에서 명명된 참조를 사용하여 연관 배열에 액세스할 수 없는 것 같습니다.
# SETUP PHP81 SYMLINKS
declare -A cgi=([path]="/opt/remi/php81/root/usr/bin/php-cgi" [filename]="php-cgi81")
declare -A config=([path]="/opt/remi/php81/root/usr/bin/php-config" [filename]="php-config81")
declare -A phpize=([path]="/opt/remi/php81/root/usr/bin/phpize" [filename]="phpize81")
declare -A pecl=([path]="/opt/remi/php81/root/usr/bin/pecl" [filename]="pecl81")
declare -A pear=([path]="/opt/remi/php81/root/usr/bin/pear" [filename]="pear81")

declare -a symlinks=("cgi" "config" "phpize" "pecl" "pear")

echo -en "[INFO]: Setting up PHP 8.1 symlinks\n"
cd /usr/bin

for symlink in "${symlinks[@]}";
do
    echo -en "[INFO]: Creating symlink for ${symlink}\n"

    # Get the array that matches the string in symlink
    props="$symlink[@]"
    # Print out the filename property eg cgi[filename], config[filename], phpize[filename]
    echo ${!props[filename]}




    echo -en "\n"

done

나에게 문제를 일으키는 코드 조각이 있습니다. 현재는 출력됩니다.

./upgrade.sh 
[INFO]: Installing php81 packages
[INFO]: Setting up PHP 8.1 symlinks
[INFO]: Creating symlink for cgi
php-cgi81 /opt/remi/php81/root/usr/bin/php-cgi

[INFO]: Creating symlink for config
php-config81 /opt/remi/php81/root/usr/bin/php-config

[INFO]: Creating symlink for phpize
phpize81 /opt/remi/php81/root/usr/bin/phpize

[INFO]: Creating symlink for pecl
pecl81 /opt/remi/php81/root/usr/bin/pecl

[INFO]: Creating symlink for pear
pear81 /opt/remi/php81/root/usr/bin/pear

The expected output is 
./upgrade.sh 
[INFO]: Installing php81 packages
[INFO]: Setting up PHP 8.1 symlinks
[INFO]: Creating symlink for cgi
php-cgi8=

[INFO]: Creating symlink for config
php-config81

[INFO]: Creating symlink for phpize
phpize81

[INFO]: Creating symlink for pecl
pecl81

[INFO]: Creating symlink for pear
pear81

이제 문제가 해결되었으므로 아래에 솔루션을 게시했지만 누군가 내 솔루션이 마음에 들지 않아서 반대 투표했지만 게시한 솔루션이 작동하고 있습니다. 하지만 무엇을 사용할지는 당신이 결정합니다. 도움을 주셔서 감사합니다.

답변1

연관 배열의 각 인덱스에 대해 간접 변수를 생성해야 합니다.

for symlink in "${symlinks[@]}";
do
    echo -en "[INFO]: Creating symlink for ${symlink}\n"

    f_var="${symlink}[filename]"
    p_var="${symlink}[path]"

    echo "filename=${!f_var}  path=${!p_var}"
done

더 복잡해지고 싶다면 cgi등을 만드세요.색인배열 및 연관 배열을 저장할 수 있습니다.색인특정 속성의 경우:

i=0; declare -A idx=([path]=$((i++)) [filename]=$((i++)))
unset cgi; declare -a cgi=( "/opt/remi/php81/root/usr/bin/php-cgi" "php-cgi81")
symlink=cgi
props="${symlink}[@]"
values=("${!props}")
echo ${values[${idx[path]}]}     # => /opt/remi/php81/root/usr/bin/php-cgi
echo ${values[${idx[filename]}]} # => php-cgi81

declare -n symlink=cgi업그레이드를 하면 확실히 훨씬 깔끔해집니다.

답변2

각각 및 키가 있는 5개의 연관 배열( cgi, config, 및 ) 을 갖는 대신 다음 phpize을 사용하는 것이 더 나을 것입니다.peclpearpathfilenamepathsfilenames각각 cgi, config, phpize, pecl 및 pear에 대한 키가 포함된 및 이름의 연관 배열 .

symlinks그런 다음 키가 포함된 배열을 반복할 수 있습니다.둘 다해시 값.

예를 들어:

#!/bin/bash

declare -A paths=(
  [cgi]=/opt/remi/php81/root/usr/bin/php-cgi
  [config]=/opt/remi/php81/root/usr/bin/php-config
  [phpize]=/opt/remi/php81/root/usr/bin/phpize
  [pecl]=/opt/remi/php81/root/usr/bin/pecl
  [pear]=/opt/remi/php81/root/usr/bin/pear
)

declare -A filenames=(
  [cgi]=php-cgi81
  [config]=php-config81
  [phpize]=phpize81
  [pecl]=pecl81
  [pear]=pear81
)

declare -a symlinks=(cgi config phpize pecl pear)

fmt='%-6s\t%-39s\t%s\n'
printf "$fmt" "KEY" "PATH" "FILENAME"
for s in "${symlinks[@]}"; do
  printf "$fmt" "$s" "${paths[$s]}" "${filenames[$s]}"
done

예제 출력:

KEY     PATH                                    FILENAME  
cgi     /opt/remi/php81/root/usr/bin/php-cgi    php-cgi81 
config  /opt/remi/php81/root/usr/bin/php-config php-config81
phpize  /opt/remi/php81/root/usr/bin/phpize     phpize81  
pecl    /opt/remi/php81/root/usr/bin/pecl       pecl81    
pear    /opt/remi/php81/root/usr/bin/pear       pear81    

답변3

ksh93으로 전환할 수 있는 옵션이 있는 경우:

#! /bin/ksh93 -
conf=(
  [cgi]=(
    path=/opt/remi/php81/root/usr/bin/php-cgi
    filename=php-cgi81
  )
  [config]=(
    path=/opt/remi/php81/root/usr/bin/php-config 
    filename=php-config81
  )
  [phpize]=(
    path=/opt/remi/php81/root/usr/bin/phpize
    filename=phpize81
  )
  [pecl]=(
    path=/opt/remi/php81/root/usr/bin/pecl
    filename=pecl81
  )
  [pear]=(
    path=/opt/remi/php81/root/usr/bin/pear
    filename=pear81
  )
)

print "[INFO]: Setting up PHP 8.1 symlinks"
cd /usr/bin || exit

for symlink in "${!conf[@]}"; do
    print -r "[INFO]: Creating symlink for ${symlink}"

    print -r ln -s -- "${conf[$symlink].path}" "${conf[$symlink].filename}"
done

다음과 같은 것을 줄 것입니다 :

[INFO]: Setting up PHP 8.1 symlinks
[INFO]: Creating symlink for cgi
ln -s -- /opt/remi/php81/root/usr/bin/php-cgi php-cgi81
[INFO]: Creating symlink for config
ln -s -- /opt/remi/php81/root/usr/bin/php-config php-config81
[INFO]: Creating symlink for pear
ln -s -- /opt/remi/php81/root/usr/bin/pear pear81
[INFO]: Creating symlink for pecl
ln -s -- /opt/remi/php81/root/usr/bin/pecl pecl81
[INFO]: Creating symlink for phpize
ln -s -- /opt/remi/php81/root/usr/bin/phpize phpize81

여기서는 다음을 수행할 수 있을 것 같습니다.

#! /bin/sh -
version=81
srcdir=/opt/remi/php$version/root/usr/bin
dstdir=/usr/bin
info() { printf '[INFO] %s\n' "$1"; }

info "Setting up PHP $version symlinks"
for file in php-cgi php-config pear pecl phpize; do
  info "Creating symlink for $file"
  ln -s -- "$srcdir/$file" "$dstdir/$file$version" || exit
done

그렇게 많이 반복할 필요가 없으며 bash 또는 ksh93에 대한 종속성을 제거할 필요가 없습니다.

답변4

나는 답을 찾았다

# SETUP PHP81 SYMLINKS
declare -A cgi=([path]="/opt/remi/php81/root/usr/bin/php-cgi" [name]="php-cgi81")
declare -A config=([path]="/opt/remi/php81/root/usr/bin/php-config" [name]="php-config81")
declare -A phpize=([path]="/opt/remi/php81/root/usr/bin/phpize" [name]="phpize81")
declare -A pecl=([path]="/opt/remi/php81/root/usr/bin/pecl" [name]="pecl81")
declare -A pear=([path]="/opt/remi/php81/root/usr/bin/pear" [name]="pear81")

declare -a files=("cgi" "config" "phpize" "pecl" "pear")

cd /usr/bin

# Adding links to new binaries
echo "[INFO]: Setting up PHP 8.1 symlinks"
for file in ${files[*]};
do
  echo "[INFO]: Creating symlink for ${file}"
  link_name="$file[name]"
  link_path="$file[path]"
  if [ ! -f "${!link_name}" ];
  then
    ln -s ${!link_path} ${!link_name}
  else
    echo "[INFO]: Symlink to ${!link_name} already exists skipping this step!"
  fi
done

관련 정보