Zsh 開(kāi)發(fā)指南(第十一篇 變量的進(jìn)階內(nèi)容)

導(dǎo)讀

之前我們已經(jīng)依次講過(guò) zsh 下的五種變量(字符串、數(shù)組、哈希表、整數(shù)、浮點(diǎn)數(shù))的基本用法。但變量的使用方面,還有一些比較進(jìn)階的內(nèi)容,這對(duì)一些比較特別的場(chǎng)景很有幫助。

typeset 命令

typeset 命令用于對(duì)變量進(jìn)行詳細(xì)的設(shè)置。我們之前在哈希表那篇見(jiàn)過(guò)它。typeset -A 可以用來(lái)定義哈希表。

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

但我們后續(xù)都使用 local,因?yàn)?local 的功能和 hashmap 是一樣的(除了不能用 -f 和 -g,這兩個(gè)選項(xiàng)不常用),并且更短更容易輸入。這里提到 typeset 命令,因?yàn)檫@個(gè)名稱(chēng)很好地反映了它的功能。但知道了這個(gè)后,我們可以繼續(xù)使用 local 命令,畢竟它們是一樣的。

typeset 命令有很多選項(xiàng),可以作用在變量上,起到各種各樣的效果。

強(qiáng)制字符串內(nèi)容為小寫(xiě)或者大寫(xiě)

# 強(qiáng)制字符串內(nèi)容為小寫(xiě)
% local -l str=abcABC && echo $str
abcabc

# 強(qiáng)制字符串內(nèi)容為大寫(xiě)
% local -u str=abcABC && echo $str
ABCABC

設(shè)置變量為環(huán)境變量

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

環(huán)境變量可以被子進(jìn)程讀取。

設(shè)置變量為只讀變量

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

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

設(shè)置數(shù)組不包含重復(fù)元素

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

設(shè)置整數(shù)的位數(shù)

# 如果位數(shù)不夠,輸出內(nèi)容會(huì)用 0 補(bǔ)全
% local -Z 3 i=5 && echo $i
005

# 如果超出范圍會(huì)被截?cái)?% local -Z 3 i=1234 && echo $i
234

進(jìn)制轉(zhuǎn)換

設(shè)置整數(shù)為其他進(jìn)制顯示:

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

可以設(shè)置 2 到 36 之間任意進(jìn)制。設(shè)置幾進(jìn)制顯示,并不影響計(jì)算,只是顯示格式不同。

用 [#n] num 也可以顯示十進(jìn)制數(shù)為 n 進(jìn)制:

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

可以用 n#num 來(lái)顯示 n 進(jìn)制整數(shù)為十進(jìn)制:

% echo $((16#ff))
255

我們可以定義一系列函數(shù)來(lái)快捷地轉(zhuǎn)換進(jìn)制,不需要使用 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))
}


# 其他進(jìn)制轉(zhuǎn)十進(jìn)制
% 0x ff
255
% 0b 1101
13

# 十進(jìn)制轉(zhuǎn)其他進(jìn)制
% p16 1234
16#4D2

同時(shí)對(duì)多個(gè)變量賦相同的值

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

綁定字符串和數(shù)組

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

# 刪除 dir 后,DIR 也會(huì)被刪除(反之亦然)
% unset dir
% echo $+DIR
0

Linux 下經(jīng)常需要處理帶分隔符冒號(hào)的字符串(比如 $PATH)。如果只修改其中某一個(gè)字段,比較麻煩。local -T 可以把字符串綁定到數(shù)組上,這樣直接修改數(shù)組,字符串內(nèi)容也會(huì)同步變化(反之亦然)。其實(shí)在 zsh 中,$PATH 字符串就是和 $path 數(shù)組綁定的,可以直接通過(guò)修改 $path 來(lái)達(dá)到修改 $PATH 的目的,這在某些場(chǎng)景會(huì)方便很多。

顯示變量的定義方式

% 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)

什么地方該加雙引號(hào)

用過(guò) bash 的讀者大概會(huì)對(duì)里邊的雙引號(hào)印象比較深刻,很多地方不加雙引號(hào)都會(huì)出錯(cuò),為了避免出錯(cuò),很多人每個(gè)變量左右都加上雙引號(hào),麻煩不說(shuō),代碼看起來(lái)也比較亂。

其實(shí) zsh 中已經(jīng)沒(méi)有那些問(wèn)題了,變量?jī)蛇厽o(wú)需加雙引號(hào),不會(huì)出現(xiàn)莫名其妙的錯(cuò)誤。但有些地方還是需要加雙引號(hào)的。

需要加雙引號(hào)的場(chǎng)景:

  1. 像這樣的包含字符或者特殊符號(hào)的字符串 "aa bb \t \n *" 出現(xiàn)在代碼中時(shí),兩邊要加雙引號(hào),這個(gè)基本不需要說(shuō)明。
  2. 在用 $() 調(diào)用命令時(shí),如果希望結(jié)果按一個(gè)字符串處理,需要加上雙引號(hào),"$()",不然的話(huà),如果命令結(jié)果中有空格,$() 會(huì)被展開(kāi)成多個(gè)字符串。
  3. 如果想將數(shù)組當(dāng)單個(gè)字符串處理,需要加雙引號(hào),array=(a b); print -l "$array"。
  4. 其他的原本不是單個(gè)字符串的東西,需要轉(zhuǎn)成單個(gè)字符串的場(chǎng)景,要加雙引號(hào)。

其余情況通常都不需要加雙引號(hào),典型的情況:

  1. 任何情況下,字符串變量的兩邊都不需要加雙引號(hào),無(wú)論里邊的內(nèi)容多么特殊,或者變量存不存在,都沒(méi)有關(guān)系,如 $str。
  2. 如果不轉(zhuǎn)換類(lèi)型(比如數(shù)組轉(zhuǎn)成字符串),任何變量的兩邊都不需要加雙引號(hào)。
  3. $1 $2 $* 這些參數(shù)(其實(shí)它們也都是單個(gè)字符串),都不需要加雙引號(hào),無(wú)論內(nèi)容是什么,或者參數(shù)是否存在。

以上的 7 種情況幾乎覆蓋了所有場(chǎng)景,如果有沒(méi)覆蓋到的,試一下即可(讓里邊的內(nèi)容包含空格、換行和其他特殊字符等等,看看結(jié)果是否符合預(yù)期)。

總結(jié)

本文簡(jiǎn)單介紹了一些比較使用的 typeset(或者 local)命令的用法,typeset 命令還有很多其他參數(shù),但一般很少用,以后我也會(huì)繼續(xù)更新。

參考

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

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

更新歷史

20170831:新增“什么地方該加雙引號(hào)”

本文不再更新,全系列文章在此更新維護(hù):github.com/goreliu/zshguide

付費(fèi)解決 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等領(lǐng)域相關(guān)問(wèn)題,靈活定價(jià),歡迎咨詢(xún),微信 ly50247。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容