不一樣的命令列 – Windows PowerShell簡介

來源:互聯網
上載者:User
引子

一直很羨慕Linux的命令提示字元(當然他們叫Shell)。Regex,管道,各種神奇的命令,組合起來就能高效完成很多複雜的任務。效率實在是高。流了n年的哈喇子以後,終於有幸用上了Win7,邂逅了cmd的升級版:Windows PowerShell。從此暗爽無比,原來Windows下也有這樣的利器呀~
看看下面的Windows指令碼,不到15行有效代碼。在Win7下只要右擊指令檔,選擇Run with PowerShell,就會自動找到最占記憶體的10個進程,然後將它們佔用的記憶體畫成一個三維餅圖,如所示。

1 # create new excel instance
2  $objExcel = New-Object -comobject Excel.Application
3  $objExcel.Visible = $True
4  $objWorkbook = $objExcel.Workbooks.Add()
5  $objWorksheet = $objWorkbook.Worksheets.Item(1)
6
7  # write information to the excel file
8 $i = 0
9 $first10 = (ps | sort ws -Descending | select -first 10)
10 $first10 | foreach -Process {$i++; $objWorksheet.Cells.Item($i,1) = $_.name; $objWorksheet.Cells.Item($i,2) = $_.ws}
11 $otherMem = (ps | measure ws -s).Sum - ($first10 | measure ws -s).Sum
12 $objWorksheet.Cells.Item(11,1) = "Others"; $objWorksheet.Cells.Item(11,2) = $otherMem
13
14 # draw the pie chart
15 $objCharts = $objWorksheet.ChartObjects()
16 $objChart = $objCharts.Add(0, 0, 500, 300)
17 $objChart.Chart.SetSourceData($objWorksheet.range("A1:B11"), 2)
18 $objChart.Chart.ChartType = 70
19 $objChart.Chart.ApplyDataLabels(5)

(1. 這個指令碼調用了Excel的COM庫。 2. 當然從命令耦合的角度來看,輸出成文字格式設定更有利,但這個例子主要想說明PowerShell的強大以及微軟產品優異的複用性。 3. 要手動啟動PowerShell,可以在開始菜單的搜尋方塊中直接鍵入PowerShell斷行符號即可
簡單領略PowerShell的強大之後,下文就從幾個方面介紹一下PowerShell相對於以往版本的命令提示字元甚至Linux Shell的優勢。

Cmdlet + Regex + Pipeline + ...

以往cmd相對於Shell有很多不足,比如命令偏少,部分命令功能偏弱,對Regex不支援等等。但現在PowerShell一下趕上來不少。2.0 RTM版內建支援414個命令(術語稱為cmdlet),支援Regex,強大的管道應用(其實管道本身的功能和以前差不多,關鍵是冒出來一堆能用管道的命令,比如more, sort, foreach等等),和系統的聯絡也比以前緊密了很多。
舉幾個例子來說明:
dir registry::HKEY_CURRENT_USER可以直接顯示註冊表相應位置的內容,可以看到dir的功能改進了不少。
ps | sort ws -Descending | select -first 10可以顯示佔用記憶體最大的10個進程,可以看到管道的靈活應用。
dir -Name | ? {$_ -match "(?<num>.).*(\k<num>)"}可以顯示出目前的目錄下檔案名稱有重複字元的檔案。比如abcda.efg,而abcd.efg則不會顯示出來。可以看到PowerShell對Regex的支援相當強大。(確切的說嚴格的Regex 已經無法實現這樣的效果,需要上下文無關文法 才能夠支援。)
以前為了示範Linux Shell的強大,Stephenjy發了一個自己的,在遇見PowerShell前覺得好神奇,所幸現在也可以實現了。:-)

 (為了節約顯示空間,PowerShell的部分顯示結果被刪除,但這個Prompt效果可以用以下指令碼驗證: function prompt {"($env:username)-($env:computername)-(`$?: $?)-(jobs: $((get-job | measure).Count))-($(get-location))`n(! $(((history)[-1]).ID + 1))->"})

大殺器 - 物件導向

Linux的設計思想決定所有的輸入和輸出都儘可能是文字格式設定,這樣可以方便各進程間的合作。同樣這也要求各個程式提供一定強度的文本解析能力。但Windows的思想與此不同,PowerShell中很多輸入輸出都不是普通的文本(plain text),而是一個個對象(objects)。因此與其說PowerShell是一種互動環境,不如說它是一種強大語言的Runtime,而這種語言甚至是物件導向的。
比如當鍵入get-process查看當前進程列表時,系統返回的是這樣的列表:

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    318       8    12948       3872    84            1728 AppleMobileD
    115       5    13816      13328    38            6920 audiodg
   1315      21    11732      10988   108            2544 CcmExec
... ...

雖然看似一般的格式化文本,但其實這是一個數組,而每個數組元素又是Process類型的對象。同.NET一脈相承,PowerShell中的所有的類都繼承自Object,且支援GetType()函數。因此我們可以執行(get-process).GetType()來看看它的類型:

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

而數組中每個元素的類型可以用(get-process)[0].GetType()查看:

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Process                                  System.ComponentM...

其中面向思想的思想非常明顯,類成員,方法,繼承都出現了。個人感覺這樣的好處並不是指望能用PowerShell寫什麼大型軟體,而是體現在另外兩個方面:首先,這樣讓內建的cmdlet及其資料結構組織清晰,符合直覺,寫代碼時速度快不容易出錯。第二,對物件導向的內建支援也為後面無縫接合.NET和COM介面提供了基礎。

站在巨人的肩膀上 - 無縫調用.NET/COM

.NET Framework中包含了一個異常強大的庫,而微軟為了保證二進位層面上跨語言的相容性,很多庫都是用COM封裝的。PowerShell的一大特色就是可以直接調用這些庫。比如前面的樣本用$objExcel = New-Object -comobject Excel.Application建立了一個Excel對象。而wikipedia上的一個指令碼更示範了這種無縫調用的強大。下面這個3句話的指令碼的作用是顯示一個RSS源最近的8篇文章的標題。注意其中網路連接,內容下載,XML解析等工作全部由.NET庫完成,正因為站在巨人的肩膀上,PowerShell在實際使用中往往左右逢源,簡潔高效。

 

$rssUrl = "http://blogs.msdn.com/powershell/rss.aspx"
$blog = [xml](new-object System.Net.WebClient).DownloadString($rssUrl)
$blog.rss.channel.item | select title -first 8
編輯,運行,調試 - IDE

Windows程式開發,尤其是基於微軟技術的開發很爽的一點就是有強大的IDE和專業的文檔作支援。不論是Windows下的Visual Studio還是Linux下的Mono Develop,甚至連PowerShell這樣的語言都有集編輯與調試為一體的IDE:Windows PowerShell ISE。有了自動完成,即時指令碼互動,調試甚至遠端偵錯,PowerShell指令碼寫起來“甚爽甚強巨”。當然文檔也是一般的強大,MSDN中關於PowerShell的部分依舊專業浩瀚。

蛋疼的偽裝 - Profile

有了PowerShell以後,很少就去cmd了。不過作為一個蛋疼的裝B男,把PowerShell偽裝成cmd也是挺有樂趣的一件事。不難發現PowerShell和cmd僅僅在表徵圖,標題,背景色,提示符,以及剛啟動時的顯示文字五個方面不同。表徵圖和背景色在捷徑屬性中可以很方便的修改。而標題和提示符的修改就要用到Profile了。所謂Profile就是在每次啟動PowerShell時都首先自動啟動並執行一段指令碼。這個指令碼的路徑在$profile變數中有設定。只要設定$host.UI.RawUI.WindowTitle為C:\windows\system32\cmd.exe就能將標題偽裝為cmd。而自訂提示符為當前路徑在PowerShell中自然萬分簡單。至於啟動時的顯示文字,只要通過/nologo參數隱藏原有的版本資訊,再列印一行cmd中的文字就好了。最終效果(關於Profile,可以參見這個連結)

 

另:進程級工作調度 – 並行支援?

==========================================================
隨著多核處理器的迅速發展,從.NET Framework 4.0開始,並行計算被一再強調。從System.Threading中新增加的並行工具類到F#這種非常適合并行化的函數式語言,微軟適時對線程級並行提供了強大的支援。但是對於進程級的工作調度,Windows似乎還相當原始。舉個最簡單的例子來說,如果我們同時向一個移動硬碟啟動5個拷貝會話的話,Windows會同時開始所有的拷貝操作。這樣磁頭會在不同的目標位置間反覆進行無意義的移動(尋道),於是在硬碟燈的狂閃中,大量時間就被浪費了。同樣當我們同時啟動數個計算量大的進程時,Windows也會試圖讓這些進程“齊頭並進”。然而為了避免某個進程被餓死,系統又不得不頻繁切換進程,於是大量的時間又被浪費在了儲存現場,進程切換,恢複現場上。這樣來看,進程級的並行做的反而不夠好。

所幸PowerShell中加入了任務調度管理功能。通過簡單的實驗,我們可以發現PowerShell對jobs的調度和Windows預設的大不相同,它一般維持和CPU核心數相同的進程高速運轉,而其它進程僅僅佔用小部分CPU時間。直到前面的進程結束工作後,後面才有新的進程遞補進入高速運轉的狀態。==========================================================
後來更仔細地做了實驗以後發現,原來Windows內建的進程調度方案就是小部分高速運轉(在我的雙核處理器上是兩個進程佔用50%CPU),大部分低速跟進(其他所有進程分享剩下的50%CPU)。這樣PowerShell的工作調度並沒有改善系統原有的現狀。同時由於PowerShell的調度系統需要佔用不小的記憶體,初始化也需要時間。在實測中甚至比預設調度慢了50%。這個實驗結果比較囧。不曉得為什麼PowerShell中為什麼要加入Job這個東西,難道僅僅為了非同步呼叫嗎?


[Update] Another post also about powershell can be found in my blog: http://grapeot.me/post/2011/09/22/Computing-Powershell-as-a-glue-language.aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.