Bash在变量中扩展变量

kef*_*ich 52 bash

我正在尝试设置我的PS1提示变量以动态选择颜色.为此,我使用颜色名称定义了一堆局部变量:

$ echo $Green
\033[0;32m
Run Code Online (Sandbox Code Playgroud)

但我希望在动态分配变量时使用它们,但我无法弄清楚如何正确扩展它们:

> colorstr="\${$color}"
> echo $colorstr
${Green}
Run Code Online (Sandbox Code Playgroud)

我试过一打组合eval,echo双引号,并且,没有似乎工作.我认为扩展变量的逻辑方式会导致错误:

> colorstr="${$color}"
-bash: ${$color}: bad substitution
Run Code Online (Sandbox Code Playgroud)

(为清楚起见,我使用的是>代替$提示字符,但我使用的是bash)

我该如何扩展该变量?即,以某种方式得到"绿色"这个词的价值\033[0;32m?并且优选地,还有bash或终端解析\033[0;32m为绿色.

编辑:我是误用${!x}eval echo $x以前的,所以我接受了这些作为解决方案.对于(也许是病态的)好奇,函数和PS1变量都在这个要点:https://gist.github.com/4383597

Jon*_*ler 58

使用eval是经典的解决方案,但bash有一个更好的(更容易控制,更少犹豫不决)的解决方案:

  • ${!colour}

Bash(4.1)参考手册说:

如果参数的第一个字符是感叹号(!),则引入一个变量间接的级别.Bash使用从参数的其余部分形成的变量的值作为变量的名称; 然后展开此变量,并将该值用于替换的其余部分,而不是参数本身的值.这被称为间接扩张.

例如:

$ Green=$'\033[32;m'
$ echo "$Green" | odx
0x0000: 1B 5B 33 32 3B 6D 0A                              .[32;m.
0x0007:
$ colour=Green
$ echo $colour
Green
$ echo ${!colour} | odx
0x0000: 1B 5B 33 32 3B 6D 0A                              .[32;m.
0x0007:
$
Run Code Online (Sandbox Code Playgroud)

(该odx命令非常非标准,但只是将其数据转换为十六进制格式,右侧显示可打印字符.由于平原echo没有显示任何内容,我需要查看回显的内容,我使用了一个我写的老朋友大约24年前.)

  • 有人[建议](http://stackoverflow.com/review/suggested-edits/1244205)使用[`xxd`](http://linuxcommand.org/man_pages/xxd1.html)而不是`odx`. (4认同)
  • 只需要使用`xxd -g1`来输出与`odx`相同的输出. (3认同)
  • 有什么关系?它显示数据。任何人都可以使用他们喜欢的任何工具来查看它。这就是 Unix 系统的美妙之处。您可以使用“od”、“xxd”、“sed -l”、“vis”等。我不喜欢“od”、“xxd”、“sed -l”或“vis”的输出目的,但它们都会起作用。由于数据的显示与答案 100% 相切,因此这并不重要。(我没有参与拒绝修订,但我可能会撤消任何此类编辑。) (2认同)

per*_*eal 13

使用eval应该这样做:

green="\033[0;32m"
colorstr="green"
eval echo -e "\$$colorstr" test           # -e = enable backslash escapes
test
Run Code Online (Sandbox Code Playgroud)

最后一次测试是绿色.