Powershell快速入門(二) Shell編程

這一部分著重于介紹Powershell的程序知識(shí)端衰,讓我們能夠編寫功能強(qiáng)大的Powershell腳本拿诸,執(zhí)行比較復(fù)雜的任務(wù)止喷。

變量

變量使用$變量名創(chuàng)建和引用擦囊。舉個(gè)例子违霞,Get-Location命令用于獲取當(dāng)前工作目錄位置,它的別名是pwd瞬场。那么我們可以使用下面的命令來創(chuàng)建一個(gè)變量买鸽,存儲(chǔ)當(dāng)前目錄位置。

C:\Users\asddf> $current=pwd

然后我們?cè)L問$current贯被,就可以獲取實(shí)際值了眼五。

C:\Users\asddf> $current

Path          
----          
C:\Users\asddf

如果知道這個(gè)命令返回的實(shí)際是.NET對(duì)象的話,我們還可以更進(jìn)一步彤灶,比方說直接訪問這個(gè)對(duì)象的Path屬性看幼,獲取值。

C:\Users\asddf> $current.Path
C:\Users\asddf

還有一個(gè)命令Get-Member幌陕,別名是gm诵姜,用于獲取對(duì)象的屬性。比方說搏熄,我們將Get-Location命令的結(jié)果通過管道傳遞給Get-Member命令棚唆,就會(huì)顯示下面的輸出。如果不了解.NET的話心例,可能感覺比較陌生宵凌。但是如果你懂得.NET和C#的話,就會(huì)像我一樣大喊一聲:“臥槽契邀,還能這樣玩摆寄?失暴!”

C:\Users\asddf> Get-Location|Get-Member


   TypeName:System.Management.Automation.PathInfo

Name         MemberType Definition                                               
----         ---------- ----------                                               
Equals       Method     bool Equals(System.Object obj)                           
GetHashCode  Method     int GetHashCode()                                        
GetType      Method     type GetType()                                           
ToString     Method     string ToString()                                        
Drive        Property   System.Management.Automation.PSDriveInfo Drive {get;}    
Path         Property   string Path {get;}                                       
Provider     Property   System.Management.Automation.ProviderInfo Provider {get;}
ProviderPath Property   string ProviderPath {get;}

如果我們要獲取對(duì)象的所有屬性坯门,使用MemberType參數(shù)。

C:\Users\asddf> pwd|gm -MemberType Property

我們還可以在變量上調(diào)用方法逗扒, 比如說將路徑轉(zhuǎn)換為全小寫古戴。


C:\Users\asddf> $current.Path.ToLower()
c:\users\asddf

最后,如果不再需要一個(gè)變量矩肩,可以使用Remove-Variable刪除變量现恼,它的別名是rv

C:\Users\asddf> Remove-Variable current

操作符

來看看Powershell中支持的操作符。

數(shù)學(xué)運(yùn)算符

首先叉袍,基本的數(shù)學(xué)運(yùn)算符都是支持的。

PS D:\Desktop> $i=5
PS D:\Desktop> $sum=3+4*($i-3)/2
PS D:\Desktop> $sum
7

前置后置自增自減運(yùn)算符也是支持的。

PS D:\Desktop> $i=0
PS D:\Desktop> $i--
PS D:\Desktop> $i++
PS D:\Desktop> ++$i
PS D:\Desktop> --$i

比較運(yùn)算符

然后是比較運(yùn)算符姐呐,這些和Linux Shell中很相似曙砂,有大于(-gt),大于等于(-ge)款侵,小于(-lt)新锈,小于等于(-le)妹笆,等于(-eq)拳缠,不等于(-ne)幾個(gè)窟坐。

字符串匹配運(yùn)算符

-like-notlike用于?*這樣的通配符哲鸳。

PS D:\Desktop> 'hello' -like '?ello'
True
PS D:\Desktop> 'hello' -notlike '?ello'
False
PS D:\Desktop> 'hello' -like '*o'
True

-match-notmatch用于正則表達(dá)式。

PS D:\Desktop> 'aabcc' -match 'a*b?c+'
True
PS D:\Desktop> 'aab' -match 'a*b?c+'
False

包含和替換運(yùn)算符

-contains查找序列中是否包含某個(gè)元素婿奔。

PS D:\Desktop> 'hello','zhang3' -contains 'zhang3'
True

-replace用于替換字符串中某個(gè)部分挤茄,當(dāng)然正則表達(dá)式也是支持的驮樊。

PS D:\Desktop> 'hello zhang3' -replace 'zhang3','yitian'
hello yitian

分隔和連接運(yùn)算符

-split-join用于將一個(gè)字符串分為幾個(gè)子部分,或者將幾個(gè)子部分組合為一個(gè)字符串练湿。

PS D:\Desktop> 'A B C DE' -split ' '
A
B
C
DE
PS D:\Desktop> 'A','B','C' -join ','
A,B,C

上面這些運(yùn)算符都是大小寫不敏感的,如果需要大小寫敏感的功能篡诽,可以在運(yùn)算符前面添加c前綴杈女。

PS D:\Desktop> 'yitian' -match 'Yitian'
True
PS D:\Desktop> 'yitian' -cmatch 'Yitian'
False

邏輯運(yùn)算符

邏輯運(yùn)算符有與(-and)达椰、或(-or)、非(-not!)以及異或(xor)幾個(gè)蝇裤,并且支持短路計(jì)算栓辜。

如果需要使用真值和假值字面量啃憎,可以使用$true$false

類型運(yùn)算符

Powershell 和.NET平臺(tái)綁定贩毕,所以它是一門強(qiáng)類型的腳本。因此我們可以在腳本中判斷數(shù)據(jù)的類型谆甜,只要使用-is-isnot運(yùn)算符即可规辱,類型需要寫到方括號(hào)中。這里的類型可以是所有合適的.NET類型浴讯。

PS D:\Desktop> 3.14 -is [Double]
True
PS D:\Desktop> 3.14 -isnot [Float]
True

重定向運(yùn)算符

這個(gè)稍微比較麻煩一點(diǎn)。

首先是>>>運(yùn)算符,用于將標(biāo)準(zhǔn)輸出流重定向到文件唠摹,前者會(huì)覆蓋已有文件,后者則是追加到已有文件末尾藕赞。

然后我們來說說日志級(jí)別,如果有使用過某些語言的日志框架的話批销,就很好理解了丘逸。在這里,2代表錯(cuò)誤湃鹊、3代表警告、4代表信息、5代表調(diào)試信息没佑。n>n>>運(yùn)算符就是用于將對(duì)應(yīng)級(jí)別的輸出重定向到文件的,這兩者的區(qū)別和前面相同。n>&1將對(duì)應(yīng)級(jí)別的輸出和標(biāo)準(zhǔn)輸出一起重定向到文件。

最后就是*>*>>了志衍,這兩者將所有輸出信息重定向到文件。

需要注意,Powershell使用Unicode編碼來輸出信息暂殖。如果你需要使用其他類型的編碼,就不能使用重定向運(yùn)算符了,而應(yīng)該使用Out-File命令。

特殊運(yùn)算符

&運(yùn)算符將它后面的命令設(shè)置為后臺(tái)運(yùn)行叁幢,當(dāng)運(yùn)行的命令需要阻塞當(dāng)前終端的時(shí)候很有用窒百。

.\\運(yùn)算符用于執(zhí)行一個(gè)腳本或命令顷帖。如果執(zhí)行的是Powershell腳本妄呕,那么腳本會(huì)在自己的作用域中執(zhí)行吊说,也就是說在當(dāng)前環(huán)境下無法訪問被執(zhí)行的腳本中的變量蠢护。

[]運(yùn)算符用于轉(zhuǎn)換變量的類型眉抬,比如說下面的代碼,就將pi變量轉(zhuǎn)換為了Float類型。

[Float]$pi = 3.14
$pi -is [Float]

.運(yùn)算符用于調(diào)用.NET對(duì)象的成員喂很,它也可以用于執(zhí)行腳本。當(dāng)它用于執(zhí)行腳本的時(shí)候,腳本會(huì)在當(dāng)前作用域中執(zhí)行豪直。所以腳本結(jié)束之后劣摇,我們可以訪問腳本中的元素。

::運(yùn)算符用于調(diào)用類中的靜態(tài)成員弓乙,例如下面就會(huì)調(diào)用.NET平臺(tái)中DateTime類的Now屬性末融。

PS D:\Desktop> [DateTime]::Now

2017年5月18日 22:45:42

..運(yùn)算符用于創(chuàng)建一個(gè)范圍閉區(qū)間,例如下面這樣暇韧。

PS D:\Desktop> 1..3
1
2
3
PS D:\Desktop> 3..1
3
2
1

-f運(yùn)算符用于格式化數(shù)據(jù)勾习,例如下面這樣。格式化方法和C#中的完全相同懈玻,所以如果不熟悉的話直接看在C#中如何格式化數(shù)據(jù)就行了巧婶。

PS D:\Desktop> 'My name is {0}, I am {1} years old' -f 'yitian',24
My name is yitian, I am 24 years old

$運(yùn)算符可以將字符串內(nèi)部的變量轉(zhuǎn)換為實(shí)際的值艺栈,例如下面這樣英岭。需要注意使用內(nèi)插操作符的時(shí)候,外部字符串需要使用雙引號(hào)湿右,否則Powershell會(huì)直接輸出字符串內(nèi)容诅妹。

PS D:\Desktop> $name='yitian'
PS D:\Desktop> $age=24
PS D:\Desktop> "My name is $name, I am $age years old."
My name is yitian, I am 24 years old.

@()運(yùn)算符用于將一系列值轉(zhuǎn)換為一個(gè)數(shù)組。假如在腳本中有一個(gè)函數(shù)可能返回0毅人、1或多個(gè)值吭狡,就可以使用這個(gè)操作符,將一系列值合并為一個(gè)數(shù)組堰塌,方便后續(xù)處理赵刑。

,逗號(hào)運(yùn)算符如果放置在單個(gè)值前面分衫,就會(huì)創(chuàng)建一個(gè)包含這個(gè)值的單元素?cái)?shù)組场刑。

條件判斷

if判斷

Powershell中的條件判斷和一般的編程語言以及Shell編程都很類似,直接看代碼就能理解蚪战。

$condition = $true

if ($condition -eq $true) {
    Write-Output "condition is $true"
}
elseif ($condition -ne $true ) {
    Write-Output "condition is $false"
}
else {
    Write-Output "other ocndition"
}

switch判斷

如果需要多重判斷牵现,可以考慮使用switch語句。一個(gè)典型的switch如下所示邀桑。

$n = 4
switch ($n) {
    1 {"n is 1"}
    2 {"n is 2"}
    3 {"n is 3"}
    default {"n is others"}
}

其實(shí)細(xì)說起來瞎疼,這個(gè)switch的坑還是不少的。例如壁畸,switch語句可以接受多個(gè)值來測(cè)試贼急,在switch語句中還可以編寫多個(gè)case相同的語句。這里我就不細(xì)說了捏萍,想具體了解的話直接看官方文檔 about_Switch吧太抓。

循環(huán)語句

提醒一下,不管是哪種循環(huán)語句令杈,在循環(huán)體內(nèi)都可以使用breakcontinue中斷/繼續(xù)循環(huán)走敌。

do循環(huán)

首先來看看do-while循環(huán),先執(zhí)行循環(huán)體逗噩,然后判斷是否滿足條件掉丽,如果滿足條件則繼續(xù)執(zhí)行。

$i = 0
do {
    $i++
    Write-Output $i
}while ($i -ne 3)

然后是do-until循環(huán)异雁,和do-while類似捶障,不過當(dāng)條件不滿足的時(shí)候才會(huì)繼續(xù)循環(huán),如果滿足條件則退出循環(huán)纲刀。

$i = 0
do {
    $i++
    Write-Output $i
}until ($i -eq 3)

while循環(huán)

while循環(huán)是先判斷循環(huán)條件残邀,滿足條件時(shí)執(zhí)行循環(huán)。

$i = 0
while ($i -lt 3) {
    Write-Output $i
    $i++
}

for循環(huán)

for循環(huán)可以看做是while循環(huán)的另一種形式,常用于固定次數(shù)的循環(huán)芥挣。

for ($i = 0; $i -ne 3; $i++) {
    Write-Output $i
}

for-each循環(huán)

for-each循環(huán)用于遍歷一個(gè)集合中的所有元素驱闷。

$array = @(1, 2, 3, 4)
foreach ($i in $array) {
    Write-Output $i
}

值得一提的是,for-each語句用在管道上時(shí)空免,還有以下一種用法空另。

<command> | foreach {<beginning command_block>}{<middle command_block>}{<ending command_block>}

使用這種方法時(shí),for-each后面可以跟三個(gè)語句塊蹋砚,第一個(gè)語句塊是開始語句塊扼菠,在循環(huán)前執(zhí)行一次,常用來初始化一些數(shù)據(jù)坝咐;第三個(gè)是結(jié)束語句塊循榆,在循環(huán)結(jié)束之后執(zhí)行一次,常用于統(tǒng)計(jì)一些循環(huán)數(shù)據(jù)墨坚;第二個(gè)就是正常的循環(huán)語句塊秧饮,會(huì)循環(huán)多次。

函數(shù)

定義函數(shù)

定義函數(shù)使用function關(guān)鍵字泽篮。

function hello {
    Write-Output 'Hello Powershell'
}

定義好函數(shù)之后盗尸,就可以使用函數(shù)名來調(diào)用函數(shù)了。

hello

函數(shù)的參數(shù)

函數(shù)當(dāng)然也可以帶參數(shù)了帽撑,參數(shù)列表有兩種寫法:第一種是C風(fēng)格的泼各,參數(shù)列表寫在函數(shù)名后面,使用小括號(hào)分隔開亏拉;第二種方式是在方法體中扣蜻,使用param關(guān)鍵字聲明參數(shù)。這兩種方法是完全等價(jià)的及塘,當(dāng)然我習(xí)慣上還是喜歡使用第一種方式莽使。

Powershell是一種強(qiáng)類型的腳本語言,所以可以在參數(shù)列表上添加參數(shù)類型磷蛹,參數(shù)類型是可選的吮旅,不過我還是推薦寫的時(shí)候帶上類型,方便閱讀和類型檢查味咳。

function Say-Hello ([string] $name) {
    Write-Output "Hello, $name"
}

function Say-Hello2 {
    param([string] $name)
    Write-Output "Hello, $name"
}

調(diào)用帶參數(shù)的函數(shù)時(shí)庇勃,需要向調(diào)用命令那樣,使用-參數(shù)名來傳遞參數(shù)槽驶,例如下面這樣责嚷。

Say-Hello -name 'yitian'

默認(rèn)參數(shù)

Powershell支持默認(rèn)參數(shù),直接用賦值號(hào)=在參數(shù)列表上指定參數(shù)默認(rèn)值即可掂铐。


function Say-Hello3 {
    param([string] $name = 'zhang3')
    Write-Output "Hello, $name"
}

位置參數(shù)

Powershell也支持位置參數(shù)罕拂,它會(huì)把所有參數(shù)包裝到$args數(shù)組中揍异,所以我們可以通過這個(gè)變量訪問所有位置的參數(shù)。例如下面爆班,將所有參數(shù)合并一個(gè)字符串衷掷,然后打印出來。

function Say-Hellos {
    $names = $args -join ','
    Write-Output "Hello, $names"
}

這個(gè)函數(shù)調(diào)用時(shí)候需要指定多個(gè)參數(shù)柿菩,注意不要在多個(gè)參數(shù)之間添加括號(hào)戚嗅,否則會(huì)變成一個(gè)數(shù)組參數(shù),而不是多個(gè)參數(shù)枢舶。

Say-Hellos 'yitian' 'zhang3' 'li4'

開關(guān)參數(shù)

開關(guān)參數(shù)沒有類型懦胞,作用僅僅是標(biāo)志是或者否。如果在使用函數(shù)的時(shí)候帶上開關(guān)參數(shù)凉泄,那么它就是的狀態(tài)躏尉,否則就是關(guān)的狀態(tài)。開關(guān)參數(shù)需要指定參數(shù)類型為switch后众。

function Answer-Hello ([switch] $yes) {
    if ($yes) {
        Write-Output "Hi"
    }
}

然后在調(diào)用時(shí)就可以看出區(qū)別了胀糜。

Answer-Hello -yes
Answer-Hello 

函數(shù)返回值

最后來說說函數(shù)返回值。這個(gè)其實(shí)也很簡單吼具,只要使用return語句就可以了僚纷。

function Add ([double]$a, [double]$b) {
    $c = $a + $b
    return $c
}

然后我們調(diào)用函數(shù)矩距,就可以看到結(jié)果了拗盒。

Add -a 3 -b 5

關(guān)于Powershell編程的知識(shí)就介紹到這里,其實(shí)如果看看官方文檔的話锥债,就知道這里介紹的也僅僅是一部分而已陡蝇。不過這一部分對(duì)于我們?nèi)粘J褂煤蛯W(xué)習(xí)基本上也夠用了。

如果要查看詳細(xì)幫助的話哮肚,可以運(yùn)行一下下面的命令登夫,這樣會(huì)顯示所有和Powershell相關(guān)的幫助文檔。

Get-Help about*

然后允趟,就可以閱讀自己感興趣的部分了恼策。比方說,如果我們想了解用Powershell編寫類潮剪,就可以使用下面的命令涣楷。如果想在瀏覽器中瀏覽器在線版本,加上-online參數(shù)即可抗碰。

Get-Help about_Classes

參考資料

https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_operators?f=255&MSPPError=-2147217396

http://windowsitpro.com/powershell/windows-powershell-operators

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末狮斗,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子弧蝇,更是在濱河造成了極大的恐慌碳褒,老刑警劉巖折砸,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異沙峻,居然都是意外死亡睦授,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門摔寨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睹逃,“玉大人,你說我怎么就攤上這事祷肯〕撂睿” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵佑笋,是天一觀的道長翼闹。 經(jīng)常有香客問我,道長蒋纬,這世上最難降的妖魔是什么猎荠? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮蜀备,結(jié)果婚禮上关摇,老公的妹妹穿的比我還像新娘。我一直安慰自己碾阁,他們只是感情好输虱,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著脂凶,像睡著了一般宪睹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蚕钦,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天亭病,我揣著相機(jī)與錄音,去河邊找鬼嘶居。 笑死罪帖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的邮屁。 我是一名探鬼主播整袁,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼樱报!你這毒婦竟也來了葬项?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤迹蛤,失蹤者是張志新(化名)和其女友劉穎民珍,沒想到半個(gè)月后襟士,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嚷量,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年陋桂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝶溶。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嗜历,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出抖所,到底是詐尸還是另有隱情梨州,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布田轧,位于F島的核電站暴匠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏傻粘。R本人自食惡果不足惜每窖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望弦悉。 院中可真熱鬧窒典,春花似錦、人聲如沸稽莉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肩祥。三九已至后室,卻和暖如春缩膝,著一層夾襖步出監(jiān)牢的瞬間混狠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國打工疾层, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留将饺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓痛黎,卻偏偏與公主長得像予弧,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子湖饱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容