Bash

如何使用變數的值作為動態變數名?

  • December 24, 2020

我一直在尋找這個問題,但要麼我不知道如何正確地問這個問題,要麼這不是一個足夠普遍的問題……

在 PHP 中,這(幾乎)是微不足道的:

function getSite(string $prefix = 'prod') {
 $DEV_SITE='dev.site.com';
 $PROD_SITE='www.site.com';
 
 $site = strtoupper("{$prefix}_site");

 return ${$site};
}

getSite();      // www.site.com
getSite('dev'); // dev.site.com

我會嘗試逐步建立它。

_SITE我有一組帶後綴的變數。

DEV_SITE=dev.site.com
PROD_SITE=www.site.com

我想用前綴作為參數呼叫一個腳本,預設為 PROD。

#!/bin/bash

PREFIX=${1:-PROD}

echo $PREFIX
---

$ script.sh dev
dev
$ script.sh
PROD

我想追"_SITE"加以$PREFIX獲取我的變數名之一:

VAR_NAME="${1:-PROD}_SITE"
echo $VAR_NAME
---

$ script.sh dev
dev_SITE
$script.sh
PROD_SITE

Awww,dev_SITE無效,但我不希望呼叫者需要知道區別。

因此,讓我們將參數設置為“不區分大小寫”,以便dev將其轉換為匹配變數名:

SITE="${1:-PROD}_SITE"
# This does NOT work:
SITE="${1:-PROD^^}_SITE"
echo ${SITE^^}
---

$ script.sh dev
DEV_SITE
$script.sh
PROD_SITE

偉大的。但是獲取該名稱的的最簡單方法是什麼?

我嘗試過的一切${SITE^^}都給了我“錯誤替換”錯誤。

echo ${$SITE^^}_PROD
echo ${${!SITE^^}_PROD}
echo ${"${SITE^^}_PROD"}
echo ${"${!SITE^^}_PROD"}

等等…

如果我分配並重新分配,它將起作用:

SITE="${1:-PROD}_SITE"
SITE=${!SITE^^}
echo $SITE
---

$ script.sh dev
dev.site.com
$ script.sh
prod.site.com

我相信這與一步完成的所有替換有關,但我也嘗試過 subshel​​l 並將名稱傳遞到其他命令中,但無法理解它。

您可以使用 a 來獲得相同的結果,而不是進行間接擴展nameref

從目前的bash聯機幫助頁:

可以使用 -n 選項為 declare 或 local 內置命令(請參閱下面的 declare 和 local 的描述)分配 nameref 屬性以創建 nameref 或對另一個變數的引用。這允許間接地操縱變數。每當 nameref 變數被引用、分配、取消設置或修改其屬性時(除了使用或更改 nameref 屬性本身),操作實際上是在由 nameref 變數的值指定的變數上執行的。nameref 通常在 shell 函式中用於引用一個變數,該變數的名稱作為參數傳遞給函式。例如,如果將變數名作為第一個參數傳遞給 shell 函式,則執行

         declare -n ref=$1

在函式內部創建一個 nameref 變數 ref,其值是作為第一個參數傳遞的變數名。對 ref 的引用和賦值,以及對其屬性的更改,被視為對其名稱被傳遞為的變數的引用、賦值和屬性修改1美元。如果 for 循環中的控制變數具有 nameref 屬性,則單詞列表可以是一個 shell 變數列表,並且在執行循環時依次為列表中的每個單詞建立名稱引用。不能為數組變數賦予 nameref 屬性。但是,nameref 變數可以引用數組變數和下標數組變數。可以使用 unset 內置的 -n 選項取消設置 Namerefs。否則,如果使用 nameref 變數的名稱作為參數執行 unset,

這是使用 nameref 的腳本版本。

#!/bin/bash

set -u

PROD_SITE='prod.example.com'
DEV_SITE='dev.example.com'
PREFIX=${1:-PROD}
SITEVAR=${PREFIX^^}_SITE

declare -n SITE=$SITEVAR

printf "Site is '%s'.\n" "${SITE}"

引用自:https://unix.stackexchange.com/questions/625908