全局 shell 变量名

Nic*_*man 7 shell variable

我需要扩大一些外壳(未环境)的变量名是主题相关的,例如B2_...在那里...也能像一个或多个不同的事情ACCOUNT_IDACCOUNT_KEYRESPOSITORY等等。

我不知道有多少变量,也不知道它们是哪些。这就是我想知道的。

我希望能够遍历B2...变量而不必将每个单独的名称放在列表中,类似于我将 glob 文件名扩展的方式。

我将 zsh 用于交互式会话,但 sh 或 bash 的解决方案也很好。

Gil*_*not 8

使用 参数扩展

$ foobar_1=x foobar_2=y foobar_3=z
$ for v in "${!foobar_@}"; do echo "$v"; done
Run Code Online (Sandbox Code Playgroud)

输出 :

foobar_1
foobar_2
foobar_3
Run Code Online (Sandbox Code Playgroud)

“取消引用”:

$ for v in "${!foobar_@}"; do echo "${!v}"; done
Run Code Online (Sandbox Code Playgroud)

输出² :

x
y
z
Run Code Online (Sandbox Code Playgroud)

  • @NickColeman,请注意在 bash 中 `${!v}` 和 `${!x*}` 不相关。`${!v}` 是特定于 bash 的,与 ksh93 的 `${!v}`(用于查询 nameref 的目标)不同。`${!x*}` 来自 ksh93,后来被 `bash` 复制。使用 `"${!foobar_@}"` 比使用 `${!foobar_*}` 更好,除非你能保证没有变量名包含在 `$IFS` 的当前值中找到的任何字符。 (2认同)

cas*_*cas 5

B2_您可以使用关联数组 ( B2) ,而不是使用名称以 开头的单个变量。例如

注意:以下内容特定于zsh. ksh并且bash也有关联数组,但初始化和使用它们的语法是不同的(见下文)。

typeset -A B2
# initialise array
B2=(ACCOUNT_ID 12345 ACCOUNT_KEY 54321 REPOSITORY somewhere)

# two different ways of adding elements to the array
B2[FOO]=bar
B2+=(NAME fred)             

for key val in ${(kv)B2}; do 
  echo "$key: $val"
done
Run Code Online (Sandbox Code Playgroud)

该示例的输出将是:

ACCOUNT_KEY: 54321
FOO: bar
REPOSITORY: somewhere
ACCOUNT_ID: 12345
NAME: fred
Run Code Online (Sandbox Code Playgroud)

您还可以使用以下命令打印整个数组(以适合在脚本或命令行中重用的形式)typeset -p

% typeset -p B2
typeset -A B2=( ACCOUNT_ID 12345 ACCOUNT_KEY 54321 FOO bar NAME fred REPOSITORY somewhere )
Run Code Online (Sandbox Code Playgroud)

ksh或 Bash 中的相同操作如下:

# initialise it
typeset -A B2
B2=([ACCOUNT_ID]=12345 [ACCOUNT_KEY]=54321 [REPOSITORY]=somewhere)

# add elements
B2[FOO]=bar
B2+=([NAME]=fred) 

# get a list of the keys and use them as indexes to get the values
for key in "${!B2[@]}"; do 
  echo "$key: ${B2[$key]}"
done

# print the entire array
typeset -p B2
Run Code Online (Sandbox Code Playgroud)


Eli*_*gan 5

巴什有compgen -v.

在 Bash 中,您可以列出以B2using 开头的变量名称:

compgen -v B2
Run Code Online (Sandbox Code Playgroud)

运行该命令会列出相同的变量,当您键入后,然后按 Tab 键时,这些变量可用作自动完成结果。(您可能需要多次按 Tab 键才能显示所有内容。)您可以交互使用,但也可以在脚本中使用它。例如:compgen -v text$textcompgen -v

$ bash -c 'compgen -v SDK'
SDKMAN_CANDIDATES_DIR
SDKMAN_CURRENT_API
SDKMAN_DIR
SDKMAN_LEGACY_API
SDKMAN_PLATFORM
SDKMAN_VERSION
Run Code Online (Sandbox Code Playgroud)

(当然,脚本可以位于文件中,而不是bash作为标志的操作数传递-c。)

的目的compgen是执行命令完成。help compgen有关它的一般信息,请参阅(在 Bash 中)的输出。尽管这可能会满足您的要求,但您可能会发现其他方法(例如Gilles Quenot 的答案中的参数扩展技术)更清楚地表达了您正在做的事情。我真的不能说哪个更好,因为这取决于您正在做什么,也许还取决于您个人的风格偏好。