理解`echo $((0x63))`


18

我在寻找一种通过命令行转换十六进制的方法,发现有一个非常简单的方法echo $((0x63))

效果很好,但是我对这里发生的事情有些困惑。

我知道$(...)通常是子外壳,其中的内容在外部命令之前进行评估。

在这种情况下它仍然是子外壳吗?我在想不是因为那意味着子shell只是在评估(0x63)这不是命令。

有人可以帮我分解命令吗?

Answers:


27

$(...)是命令替换(不仅是子shell),而且$((...))是算术扩展。

当您使用时$((...))...会将解释为算术表达式。这意味着,除其他外,十六进制字符串将被解释为数字并转换为十进制。然后将整个表达式替换为该表达式求值的数值。

像参数扩展和命令替换一样,$((...))应引述为不受Shell的单词拆分和文件名限制的影响。

echo "$(( 0x63 ))"

附带说明,在算术表达式中出现的变量不需要它们$

$ x=030; y=30; z=0x30
$ echo "$(( x + y +x ))"
78

2
还要注意,由于$((...))与命令替换冲突,因此必须记住写echo "$( (echo x; echo y) | tr xy yx)"而不是echo "$((echo x; echo y) | tr xy yx)"(尽管某些shell仍会接受后者,YMMV)。
斯特凡Chazelas

@StéphaneChazelas您如何$(( ))制作受分词或通配符影响的输出?
Hauke Laging '17

3
@HaukeLaging , IFS=9; echo $((0x63))。又见遗忘在bash引用变量的安全隐患/ POSIX壳What about [ $# -gt 1 ]部分)
斯特凡Chazelas

3

这不是子shell,而是算术评估。来自man bash

((表达))

根据以下算术评估中所述的规则评估表达式。如果表达式的值不为零,则返回状态为0;否则,返回值为0。否则返回状态为1。这完全等同于let“表达式”。


9
((...))与不太一样$((...))。两者都进行算术运算,但是后者被结果值替换为字符串。
库萨兰达
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.