Zsh 开发指南(第十一篇 变量的进阶内容)

导读

之前我们已经依次讲过 zsh 下的五种变量(字符串、数组、哈希表、整数、浮点数)的基本用法。但变量的使用方面,还有一些比较进阶的内容,这对一些比较特别的场景很有帮助。

typeset 命令

typeset 命令用于对变量进行详细的设置。我们之前在哈希表那篇见过它。typeset -A 可以用来定义哈希表。

% typeset -A hashmap=(aa bb cc dd)

但我们后续都使用 local,因为 local 的功能和 hashmap 是一样的(除了不能用 -f 和 -g,这两个选项不常用),并且更短更容易输入。这里提到 typeset 命令,因为这个名称很好地反映了它的功能。但知道了这个后,我们可以继续使用 local 命令,毕竟它们是一样的。

typeset 命令有很多选项,可以作用在变量上,起到各种各样的效果。

强制字符串内容为小写或者大写

# 强制字符串内容为小写
% local -l str=abcABC && echo $str
abcabc

# 强制字符串内容为大写
% local -u str=abcABC && echo $str
ABCABC

设置变量为环境变量

% local -x str=abc
# 通常使用 export,功能一样
% export str=abc

环境变量可以被子进程读取。

设置变量为只读变量

% local -r str1=abc
# 通常使用 readonly,功能一样
% readonly str2=abc

% str1=bcd
zsh: read-only variable: str1
% str2=bcd
zsh: read-only variable: str2

设置数组不包含重复元素

% local -U array=(aa bb aa cc) && echo $array
aa bb cc

设置整数的位数

# 如果位数不够,输出内容会用 0 补全
% local -Z 3 i=5 && echo $i
005

# 如果超出范围会被截断
% local -Z 3 i=1234 && echo $i
234

进制转换

设置整数为其他进制显示:

% local -i 16 i=255
% echo $i
16#FF

可以设置 2 到 36 之间任意进制。设置几进制显示,并不影响计算,只是显示格式不同。

用 [#n] num 也可以显示十进制数为 n 进制:

% echo $(([#16] 255))
16#FF

可以用 n#num 来显示 n 进制整数为十进制:

% echo $((16#ff))
255

我们可以定义一系列函数来快捷地转换进制,不需要使用 bc 等外部命令:

0x() {
    echo $((16#$1))
}

0o() {
    echo $((8#$1))
}

0b() {
    echo $((2#$1))
}

p16() {
    echo $(([#16] $1))
}

p8() {
    echo $(([#8] $1))
}

p2() {
    echo $(([#2] $1))
}


# 其他进制转十进制
% 0x ff
255
% 0b 1101
13

# 十进制转其他进制
% p16 1234
16#4D2

同时对多个变量赋相同的值

% local {i,j,k}=123
% echo $i $j $k
123 123 123

绑定字符串和数组

% local -T DIR dir
% dir=(/a /b/c /b/d /e/f)
% echo $DIR
/a:/b/c:/b/d:/e/f

# 删除 dir 后,DIR 也会被删除(反之亦然)
% unset dir
% echo $+DIR
0

Linux 下经常需要处理带分隔符冒号的字符串(比如 $PATH)。如果只修改其中某一个字段,比较麻烦。local -T 可以把字符串绑定到数组上,这样直接修改数组,字符串内容也会同步变化(反之亦然)。其实在 zsh 中,$PATH 字符串就是和 $path 数组绑定的,可以直接通过修改 $path 来达到修改 $PATH 的目的,这在某些场景会方便很多。

显示变量的定义方式

% array=(aa bb cc)
% local -p array
typeset -a array=(aa bb cc)

% array+=(dd)
% local -p array
typeset -a array=(aa bb cc dd)

什么地方该加双引号

用过 bash 的读者大概会对里边的双引号印象比较深刻,很多地方不加双引号都会出错,为了避免出错,很多人每个变量左右都加上双引号,麻烦不说,代码看起来也比较乱。

其实 zsh 中已经没有那些问题了,变量两边无需加双引号,不会出现莫名其妙的错误。但有些地方还是需要加双引号的。

需要加双引号的场景:

  1. 像这样的包含字符或者特殊符号的字符串 "aa bb \t \n *" 出现在代码中时,两边要加双引号,这个基本不需要说明。
  2. 在用 $() 调用命令时,如果希望结果按一个字符串处理,需要加上双引号,"$()",不然的话,如果命令结果中有空格,$() 会被展开成多个字符串。
  3. 如果想将数组当单个字符串处理,需要加双引号,array=(a b); print -l "$array"
  4. 其他的原本不是单个字符串的东西,需要转成单个字符串的场景,要加双引号。

其余情况通常都不需要加双引号,典型的情况:

  1. 任何情况下,字符串变量的两边都不需要加双引号,无论里边的内容多么特殊,或者变量存不存在,都没有关系,如 $str
  2. 如果不转换类型(比如数组转成字符串),任何变量的两边都不需要加双引号。
  3. $1 $2 $* 这些参数(其实它们也都是单个字符串),都不需要加双引号,无论内容是什么,或者参数是否存在。

以上的 7 种情况几乎覆盖了所有场景,如果有没覆盖到的,试一下即可(让里边的内容包含空格、换行和其他特殊字符等等,看看结果是否符合预期)。

总结

本文简单介绍了一些比较使用的 typeset(或者 local)命令的用法,typeset 命令还有很多其他参数,但一般很少用,以后我也会继续更新。

参考

http://www.bash2zsh.com/zsh_refcard/refcard.pdf

http://www.linux-mag.com/id/1079/

更新历史

20170831:新增“什么地方该加双引号”

本文不再更新,全系列文章在此更新维护:github.com/goreliu/zshguide

付费解决 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等领域相关问题,灵活定价,欢迎咨询,微信 ly50247。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容