【问题标题】:How to put environment variable in Array?如何将环境变量放入Array?
【发布时间】:2020-03-16 19:10:48
【问题描述】:

DIR1, DIR2, .... DIRN 来自包含一些目录路径的环境变量。 例子

export DIR1="/users/abcd"
export DIR2="/users/abcd/xyz"
.
.
.

我怎么知道环境变量中有多少个 DIR_ 并将所有这些放在下面的数组中

arr=(DIR1 DIR2 ... . . DIRN)
i=0
while [ $i -lt ${#arr[@]} ] 
do
      cd ${arr[$i]}
      i=`expr $i + 1`
done

【问题讨论】:

  • 看起来 DIR1 根本不是来自环境,而是在您的脚本中明确设置。
  • yes @WilliamPursell 有一个 groovy 脚本,它将输入目录作为映射并将其导出到 shell 脚本中。
  • 它不会出现在环境变量中吗?
  • 变量 DIR1 等将在任何子 shell 的环境中,也许这就是您感兴趣的。
  • 我很惊讶这里还没有答案使用 bash 的内置功能来迭代以固定前缀开头的变量名。如果10个小时左右还是没有这样的答案,那我就加一个。

标签: linux bash shell sh ksh


【解决方案1】:

对于环境变量的值中可能包含换行符的情况,您可以使用此脚本,该脚本使用 gnu 版本的 printenvawk

mapfile -t arr < <(printenv -0 | awk -v RS='\0' -F= '/^DIR/{print $1}')

然后检查您的数组内容为:

declare -p arr

【讨论】:

  • 你的回答对我来说看起来很合理,但是当我尝试这种方法时,我得到(很可能来自进程重定向)错误消息 bash: /dev/fd/62: No such file或目录。即使我用无辜的echo 123 替换整个管道,我也会明白这一点。有什么想法,为什么?使用 Cygwin 版本的 bash 4.4.12(3)
  • 不不,你不能在ksh 中这样做。您必须根据您的相关标签使用bash。先运行bash,然后在应答中运行这个命令。
  • @anubhava :重新启动后错误消息消失了。我不知道我在我的环境中有什么奇怪的价值会导致我观察到的那种效果。我现在只能说,您的解决方案现在似乎很有效。
  • @satishkumar:我觉得有点奇怪,你明确要求 bash 解决方案(假设你使用了 bash 标签)你的问题,现在,在评论中,也请求一个 ksh。也许在此之后,您想要一个在 Zsh 中工作,一个在 Posix shell 中工作。如果您需要多个 shell 的解决方案,请在评论中明确写下,或者更好的是,针对各个 shell 提出单独的问题。
  • @anubhava 我很抱歉。我对这个平台很陌生。
【解决方案2】:

"${!prefix@}" 扩展为以prefix 开头的变量名称列表。在目前的情况下,可以这样使用:

#!/usr/bin/env bash
[ -n "$BASH_VERSION" ] || { echo "This must be run with bash, not /bin/sh" >&2; exit 1; }

arr=( )
for varname in "${!DIR@}"; do
  [[ $varname =~ ^DIR[[:digit:]]+$ ]] || continue ## skip DIRSTACK or other names that don't match
  arr+=( "${!varname}" )
done

【讨论】:

  • @Matthieu,谢谢你提醒我。今天早上我完全忘记了这个问题,如果不是你的信息,我不会回来。
【解决方案3】:
printenv   |  awk -F'=' '{if ($0 ~ /^DIR/) print $2; }'

演示:

:-:export DIR1="/users/abcd"
:-:export DIR2="/users/abcd"
:-:export DIR4="/usasders/abcd"
:-:printenv   |  awk -F'=' '{if ($0 ~ /^DIR/) print $2; }'
/usasders/abcd
/users/abcd
/users/abcd
:-:

【讨论】:

  • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
  • @veben 我已经编辑了帖子并添加了演示。您正在寻找的答案是什么?
【解决方案4】:

我的回答是指您问题的 书面 部分,您在其中要求 环境 变量,因为从您给出的示例中,不清楚变量是否在question 实际上是环境变量或仅仅是 shell 变量。

由于printenvNAME=VALUE 表示形式为您提供了环境变量列表,您可以这样做

arr=($(printenv|grep '^DIR[0-9]'|cut -f 1 -d =))

grep 选择以 DIR 开头的行,后跟至少一位数字。根据您的需要调整模式。

cut 只选择等号的左侧部分,即名称。

此解决方案假定您没有包含嵌入换行符的环境变量。在这种情况下,我建议使用一种编程语言,它会为您提供可以循环访问的环境变量列表。 PerlRubyJava 都可以。

【讨论】:

  • BashPitfalls #50。以这种方式填充数组允许意外的字符串替换和全局扩展来修改您的值。
  • @user1934428,当然可以可靠地列出和检索 bash 中的环境和其他变量,即使它们的值包含换行符。 f/e,可以使用compgen -v获取没有值的名称,然后indirect expansion 检索每个名称的值。
  • ...或者,在 Linux 上,可以使用 while IFS= read -r -d '' vardef; do name=${vardef%%=*}; value=${vardef#*=}; printf '%q=%q\n' "$name" "$value"; done &lt;/proc/self/environ 之类的东西来迭代仅在进程初始化时设置的环境变量。
  • @CharlesDuffy:感谢您的帮助。与OP的问题没有真正的关系,但是您是否偶然知道compgen -v之类的东西是否也可以在Zsh中完成?我的 Zsh (5.5.1) 没有内部命令 compgen。
  • @user1934428 不,我不能和 zsh 说话——15 多年前我就放弃了它,当时我意识到它让我养成了在需要编写脚本时导致代码错误的习惯对于非 zsh shell;在此期间,我几乎忘记了我所知道的一切。如果您在知识库中找不到特定于 zsh 的答案,请随时提出专门为 zsh 标记的新问题。
猜你喜欢
  • 2023-02-15
  • 2018-04-23
  • 2013-01-07
  • 2022-10-04
  • 1970-01-01
  • 2015-06-22
  • 2015-06-07
  • 2015-10-05
  • 2012-05-08
相关资源
最近更新 更多