![似乎无法在 bash 中访问具有命名引用的关联数组](https://linux22.com/image/207926/%E4%BC%BC%E4%B9%8E%E6%97%A0%E6%B3%95%E5%9C%A8%20bash%20%E4%B8%AD%E8%AE%BF%E9%97%AE%E5%85%B7%E6%9C%89%E5%91%BD%E5%90%8D%E5%BC%95%E7%94%A8%E7%9A%84%E5%85%B3%E8%81%94%E6%95%B0%E7%BB%84.png)
# 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
、pecl
和pear
),每个数组都有path
和filename
键,你最好只拥有二paths
名为和的关联数组filenames
,每个数组都有 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