Powershel支持變量,這個功能對用慣了CMD的開發(fā)人員來說,那簡直就是驚喜——終于可以結束總是把環(huán)境變量搞亂的痛苦日子了。
Powershell的變量是以$號作為前綴的,所有變量都必須以$號開頭,比如$var1, $my_var_2……。按照慣例,變量名當然是字母數(shù)字和下劃線的組合。不過Powershell的變量不完全符合慣例——它的變量幾乎允許任意字符。不過,當你準備使用“$my var”這個“變量”的時候,你會得到一個錯誤,因為,對于包含特殊字符的變量名,需要點特別的標記——用一對大括號括起來——當然,如果你不嫌麻煩的話,你也可以用同樣的手段來包裝一下不含特殊字符的變量名。來看示例:
- PS F:\> $var1 = 1
- PS F:\> ${my var} = 2
- PS F:\> "$var1, ${my var}, ${var1}"
- 1, 2, 1
- PS F:\>
驚喜到這里還未結束。Powershell的變量都是有類型的,因為它們都對應于.NET中的基本數(shù)據(jù)類型,或者對象。做個實驗:
- PS F:\> ${my var}.getType().fullName
- System.Int32
- PS F:\> $var2 = "James Fancy"
- PS F:\> $var2.getType().fullName
- System.String
- PS F:\>
可以看到,剛才定義的${my var}是Int32類型,而新定義的$var2是String類型,而它們的類型,完全是由它們的值決定的,這個,仔細觀察一下定義這兩個變量的那兩條命令就明白了。于是,這里引發(fā)一個問題,既然變量是有類型的,那是否可以指定類型呢?答案是肯定的:
- PS F:\> [long] $var3 = 1
- PS F:\> $var3.getType().fullName
- System.Int64
- PS F:\> [string] $var3 = $var3
- PS F:\> $var3.getType().fullName
- System.String
- PS F:\>
這個例子很好的解釋了,可以通過前綴由方括符包含的類型名稱來為變量指定類型,而且還帶出兩點驚喜:第一,變量的類型是可以改變的;第二,從長整型到字符串類型可以直接轉換而不需要特別的工具或者函數(shù),當然,這還可以擴展到其它類型的轉換。
現(xiàn)在我們需要了解一下,常見的類型都有哪些呢?簡單的列舉一下:bool、char、byte、sbyte、int16、int32或int、int64或long、uint16、uint32、uint64、float或single、double、string、datetime、guid、xml、switch……除此之外,還有另外一些內置的類型,以及.NET庫中的所有類和結構——太給力了!
這些內置數(shù)據(jù)類型之間大多可以自動轉換。在表達式中,如果存在混合類型的運算,多數(shù)時候是以先出現(xiàn)的那個變量的類型為準來進行運算,比如
- PS F:\> 2 + "2" # 先出現(xiàn)整型,后面的字符串轉換為整進行整數(shù)運算
- 4
- PS F:\> "2" + 2 # 先出現(xiàn)字符串型,后面的整形轉換成字符符進行連接運算
- 22
- PS F:\>
變量是有了,Powershell能定義常量么?當然可以,不過需要用new-variable來定義:
- PS F:\> new-variable myConst "James Fancy" -option constant
- PS F:\> $myConst
- James Fancy
- PS F:\>
常量是不能改變的,嘗試給它重新賦值會拋出錯誤。這不是悲劇,悲劇的是,常量不能被刪除,就算加上-force參數(shù)也不能被刪除。
- PS F:\> del -force variable:myConst
- Remove-Item : 無法刪除變量 myConst,因為該變量為常量或者為只讀變量。如果該變量
- 為只讀變量,請指定 Force 選項,然后重試此操作。
- 所在位置 行:1 字符: 4
- + del <<<< -force variable:myConst
- + CategoryInfo : WriteError: (myConst:String) [Remove-Item], Sess
- ionStateUnauthorizedAccessException
- + FullyQualifiedErrorId : VariableNotRemovable,Microsoft.PowerShell.Comman
- ds.RemoveItemCommand
- PS F:\>
不過這個常量并不是永駐于你的操作系統(tǒng)了,只需退出當前控制臺,再開啟一個新的控制臺,你就會發(fā)現(xiàn),一些都是嶄新的,沒有之前定義的一切東西:函數(shù)、變量以及刪不掉的常量。
話說回來,如果需要一個可以刪除的常量,那不妨考慮下只讀變量,只讀變量有兩種方式產(chǎn)生,一種是跟定義常量一樣,在通過new-variable命令定義的時候指定-option為readonly;另一種是在變量已經(jīng)存在的情況下,改變其選項。
- PS F:\> new-variable rVar "James" -option readonly # 第一種方法
- PS F:\> $rVar2 = "Fancy" # 第二種方法,先定義一個普通變量
- PS F:\> (get-variable rVar2).options = "readonly" # 再通過get-varialbe取得變量對象并改變選項
- PS F:\> # 當然上面這句話也可以用set-varialbe命令來完成,就像這樣
- PS F:\> # set-variable rVar2 -option readonly
- PS F:\>
只讀變量是可以被刪除的,當然需要-force參數(shù)。只讀變量也可以變回普通變量,只需要改變其選項,當然也需要-force參數(shù)。
- PS F:\> del variable:rVar -force # 刪除只讀變量rVar
- PS F:\> set-variable rVar2 -option none -force # 將rVar2變成普通變量
- PS F:\>
上面提到變量的時候已經(jīng)多次使用了“variable:變量名”這種形式的東東。這里的“varialbe:”被稱作Device,就好像C:、D:、E:、F:一樣。也許理解起來有點困難,不過,把它想像成“命名空間”應該就好理解了。
上面的示例中定義了$var1、$var2、${my var}等變量,其它它們的全稱應該是$variable:var1、$variable:var2、${varialbe:my var}。除了variable之外,常用的命名空間還有env、function、alias等。
如果想知道Powershell有哪些命令可以用,help已經(jīng)說明了,可以用get-command來查看。在控制臺輸入help get-command之后,就可以看到get-command的用法。
在get-command的語法中可以看到一個-CommandType參數(shù),它允許get-command按類型查詢命令,其中類型包括Alias、Function、Filter、Cmdlet、ExternalScript、Application和Script。最后一項scrip我沒搞懂,不過前面幾項分別是:
√ Alias,別名,通過set-alias命令為Cmdlet、Function等命令設置的一個簡單易記的名稱。
√ Function,函數(shù),你懂的。
√ Filter,一種特別的函數(shù),用于在重定向操作中過濾對象列表。
√ Cmdlet,可以理解為Powershell的內置命令——當然,Powershell的內置命令是可以擴展的。
√ ExternalScript,所有在路徑(由$env:path變量的值說明)中的.ps1腳本
√ Application,毫無懸念,路徑中的.exe文件(其實應該說是PE文件,因為.dll等也算在內)
Cmdlet是Powershell的內置命令,比如之前用到的get-command就是一個Cmdlet。按Powershell的規(guī)范,Cmdlet的名字都是由動詞和賓語構成的,以說明這個Cmdlet的作用,其結構是“動詞-賓語”。比如get-command的意思就很明顯,是獲取命令相關的信息的。
同樣,通過help get-command,可以在其說明文檔中找到get-command的第二種語法里有一個-verb參數(shù),提供通過動詞來查找命令的功能。這里的動詞包括get、set、test……很多,而且可以自己定義。比如“get-command -verb go”找不到有匹配的命令,但是如果定義了一個名叫"go-url"的函數(shù)之后,再運行“get-command -verb go”就可以將剛定義的“go-url”顯示出來了,就像這樣:
- PS F:\> get-command -verb go
- PS F:\> function go-url() { "going..." }
- PS F:\> get-command -verb go
- CommandType Name Definition
- ----------- ---- ----------
- Function go-url param()...
- PS F:\>
上面提到Cmdlet是可以擴展的,的確如此。你可以自己按照規(guī)范來寫DLL擴展Cmdlet,當然那不是一件簡單的事情。對于腳本的常規(guī)用法來說,它太復雜了,所以我在短期內沒準備去學習它。
我們曾經(jīng)多次使用help命令,其實它是一個別名——或者說得擬人一點,叫昵稱。help是get-help的另一個名字,輸入get-help很麻煩,因為它包含8個字符,其中一個還是符號,所以懶人們發(fā)明了“別名”,為它取了另一個更簡明的名字,help。
當然,并不是只有get-help享受了這個待遇。如果你在控制臺中鍵入alias命令,就可以看到目前已經(jīng)定義了的所有別名,以及它們對應的原始命令。當然,這里顯示的只是已經(jīng)定義的,如果你愿意,隨時可以添加新的別名。比如剛才的示例中定義了一個go-url函數(shù),那么現(xiàn)在為它取個新名字,叫url:
- PS F:\> set-alias url go-url
- PS F:\> url
- going...
- PS F:\>
甚至,還可以為別名指定別名,比如
- PS F:\> set-alias myurl url
- PS F:\> get-alias url,myurl
- CommandType Name Definition
- ----------- ---- ----------
- Alias url go-url
- Alias myurl url
- PS F:\>
這里,get-alias會顯示指定的別名列表中每個別名的信息。
如果不想要某個別名了,可以用del命令刪除它——哦,del也是個別名,真實的命令是remove-item。
- PS F:\> del alias:url
- PS F:\>
更多建議: