引言
是不是覺得同樣是活著,別人為啥就能做這么多事呢?
是不是經(jīng)常8小時(shí)班上下來,卻不曉得自己干了些啥?
是不是習(xí)慣于在Email, BBS, Google Reader間切換,感覺也挺忙的呢?
你需要時(shí)間管理!
你知道自己一天寫了多少代碼嗎?
你了解自己一周有多少時(shí)間在網(wǎng)上游蕩嗎?
你能說出一個(gè)月有幾天陪著家人嗎?
你需要PowerShell!
管理?先記錄!
時(shí)間管理就是用最少的時(shí)間做最多的事。和優(yōu)化程序的性能一樣,為了提升時(shí)間的利用率,得先知道自己的時(shí)間都花在什么地方。如果上班時(shí)間有50%都浪費(fèi)在瑣事上,剩下的一半時(shí)間再集中精力,一天的成效也好不到哪去。相應(yīng)的,如果90%的時(shí)間都在干活,相比于竭力縮小剩下的走神時(shí)間,反不如稍稍提高一點(diǎn)效率。射箭強(qiáng)調(diào)有的放矢,治病講求對癥下藥。知曉瓶頸所在是優(yōu)化的前提。
那么如何知道自己的弱點(diǎn)在什么地方?記錄,養(yǎng)成記錄的習(xí)慣。
試想當(dāng)一周結(jié)束,你看到一張統(tǒng)計(jì)表:這周加班5小時(shí),所有工作時(shí)間中,27%寫代碼,22%開會,16%寫文檔,35%偷菜。寫了3600行代碼,出現(xiàn)了75個(gè)bug,自查出69個(gè)。是不是覺得時(shí)間管理一下子簡單了很多?多寫代碼少偷菜,少生孩子多養(yǎng)豬唄。當(dāng)然這個(gè)“偷菜”可以是很多東西,辦公室政治,信息上癮,搭公交上下班...如果沒有這個(gè)表,恐怕很多時(shí)候自己都意識不到有這樣多的時(shí)間浪費(fèi)在了瑣事上,還在苦惱怎么提高效率呢。
記錄不僅可以為管理服務(wù),這個(gè)行動本身就能給人帶來動力?!拔崛杖∥嵘?,則知明而行無過矣?!庇涗洸粌H僅是動動筆,當(dāng)回顧過去所為的時(shí)候,它更是一個(gè)“省”的過程。為什么前兩周每周都是3000+行代碼這周只有1500-?為什么昨天老婆發(fā)了3次火而此前3周一共才生兩次氣?為什么...?聲色犬馬,光影浮華,我們太容易忽略一些就發(fā)生在我們身邊的變化,而隨手的記錄,說不定就會讓我們即時(shí)警醒。
可是...難道要我每次上網(wǎng)都要記下來上了幾分鐘,每次老婆發(fā)火都要立馬翻個(gè)小本子出來記個(gè)陳年?duì)€芝麻帳嗎?
記錄太煩人,秘書來幫忙
當(dāng)然不,你需要的只是一個(gè)秘書。這個(gè)人心隔肚皮的世界小蜜可要不起,不過電腦,手機(jī)這些冷冰冰的塑料家伙倒真可以成為你的伙伴。我沒有能力搜羅出一系列神通廣大的軟件來一下告訴你上個(gè)月偷了幾棵菜上了多少網(wǎng),但也許可以啟發(fā)你打造自己的電腦秘書。
讓電腦這個(gè)不怕麻煩的家伙說出你用電腦干了什么事可是他的拿手好戲。我們就從這里開始吧!可是...用什么工具呢?PowerShell呀!就像我們上次介紹的,這個(gè)全新的命令行工具可以輕松地獲取系統(tǒng)信息,接合.NET對象,管理后臺任務(wù),還能調(diào)用Excel等高級數(shù)據(jù)分析工具。數(shù)據(jù)記錄、處理、呈現(xiàn)、挖掘一條龍服務(wù),舍我其誰呢?
觀察
整個(gè)時(shí)間記錄的思路比較簡單。電腦反正不怕麻煩,可以每過半分鐘就來看看你在干啥。等一天結(jié)束的時(shí)候再把報(bào)表拿給你看就好。
可是問題來了,電腦怎么知道你是在上網(wǎng),在寫文檔還是在寫代碼呢?哈,對于PowerShell來說,這個(gè)可簡單了。還記得PowerShell中傳遞的是一個(gè)個(gè)對象嗎?其中每個(gè)命令返回的都是含有豐富信息的對象,我們可以大加利用。至于怎么知道每個(gè)對象有哪些屬性,可以用get-member這個(gè)函數(shù)來查看。比如Get-process可以得到當(dāng)前所有進(jìn)程,我們可以用get-process | get-member來查看“進(jìn)程”有哪些屬性屬性。當(dāng)然由于ps是get-process的alias,我們也可以用ps | get-member來查看。
復(fù)制代碼 代碼如下:
Name MemberType Definition
---- ---------- ----------
... ...
MainModule Property System.Diagnostics.ProcessModule M...
MainWindowHandle Property System.IntPtr MainWindowHandle {get;}
MainWindowTitle Property System.String MainWindowTitle {get;}
MaxWorkingSet Property System.IntPtr MaxWorkingSet {get;s...
MinWorkingSet Property System.IntPtr MinWorkingSet {get;s...
... ...
好多...一共有90個(gè)呢。注意到其中的MainWindowTitle了嗎?這個(gè)就是該進(jìn)程主窗口的標(biāo)題。讓我們用ps | ? {$_.MainWindowTitle} | select MainWindowTitle來看看當(dāng)前系統(tǒng)主窗口的標(biāo)題是什么:
復(fù)制代碼 代碼如下:
MainWindowTitle
---------------
Start Page - Microsoft Visual Studio
Computing Life - 博客園 - Windows Internet Explorer
你的C:\&;能干啥?(1) -- 用PowerShell打造時(shí)間管理小秘書 - Microsoft Office One...
Untitled - Message (HTML)
Windows PowerShell
Windows Task Manager
Document1 - Microsoft Word
恩恩,能看出來不少東西呢。比如說在用IE瀏覽博客園,在用Word寫文檔,在用Visual Studio寫代碼等等。還真得感謝這些軟件的設(shè)計(jì)者,把軟件的名字都放在窗口的標(biāo)題上了,否則我們的統(tǒng)計(jì)還挺有難度。下面的事情就簡單了,我們可以用正則表達(dá)式匹配每個(gè)標(biāo)題,比如含有Internet Explorer的就是在上網(wǎng),含有Visual Studio的說明在寫代碼等等。只要定時(shí)來統(tǒng)計(jì)一下,一天有多長時(shí)間上網(wǎng),多長時(shí)間寫代碼就很容易算出來了。
記錄
至此“觀察”這一步算是解決了。可是怎么“記錄”呢?這個(gè)也挺簡單,用個(gè)數(shù)組就搞定,每次查看如果發(fā)現(xiàn)Internet Explorer就把上網(wǎng)+1,發(fā)現(xiàn)Microsoft Word就把文檔+1就好了呀。好在PowerShell早就想到了這一切,就算不動用.NET中強(qiáng)大的數(shù)據(jù)結(jié)構(gòu),它也內(nèi)置了Hash-Table這一數(shù)據(jù)類型,非常適合我們完成統(tǒng)計(jì)任務(wù)。
比如我們想監(jiān)測上網(wǎng),寫代碼和寫文檔的時(shí)間,只要編寫這樣的腳本就好:
復(fù)制代碼 代碼如下:
$timeInterval = 30 #每30s監(jiān)測一次
$record = @{"上網(wǎng)" = 0; "編程" = 0; "文檔" = 0}
$count = 0
while ($true)
{
$titles = ps | ? {$_.MainWindowTitle} | select MainWindowTitle
$titles | % { #這部分用來匹配窗口標(biāo)題并進(jìn)行統(tǒng)計(jì),可以自由定義
if ($_ -match "Internet Explorer") {$record["上網(wǎng)"]++}
if ($_ -match "Visual Studio") {$record["編程"]++}
if ($_ -match "Microsoft Word") {$record["文檔"]++}
if ($_ -match "Microsoft Office OneNote") {$record["文檔"]++}
if ($_ -match "Microsoft PowerPoint") {$record["文檔"]++}
}
sleep($timeInterval) #將線程轉(zhuǎn)入睡眠,每30秒喚醒一次
$count = ($count + 1) % 10 #為了防止數(shù)據(jù)丟失,每10次記錄寫入文件一次
if ($count -eq 0) {$record > d:\temp\timeRecord.txt}
}
代碼非常簡單,大意就是把每個(gè)窗口的標(biāo)題進(jìn)行匹配并統(tǒng)計(jì)。執(zhí)行起來也很快,在毫秒量級。由于每30秒才執(zhí)行一次,所以對系統(tǒng)幾乎沒有影響。
如果要求不高的話,只要在開著電腦的時(shí)候后臺運(yùn)行這個(gè)腳本就好了。每天下班的時(shí)候去看看記錄文檔,時(shí)間如何花費(fèi)自然一目了然。但是這樣畢竟要占用PowerShell的會話窗口,同時(shí)無法實(shí)時(shí)得知當(dāng)前的統(tǒng)計(jì)結(jié)果。因此下面將試圖演示如何讓這個(gè)腳本在后臺執(zhí)行,同時(shí)使我們能及時(shí)看到當(dāng)前的時(shí)間利用率。如果你對這方面內(nèi)容不感興趣的話可以直接跳到下一節(jié),這部分不會影響后面的閱讀。:-)
PowerShell提供了強(qiáng)大的后臺任務(wù)管理,使用起來也一樣簡單。我們可以把這個(gè)腳本存成一個(gè)腳本文件,比如Motinor.ps1,然后在PowerShell中鍵入start-job {c:\users\grapeot\Monitor.ps1}就可以在后臺運(yùn)行它了。我們可以看到PowerShell返回以下文字之后就又回到了命令行,于是可以繼續(xù)處理其他事務(wù):
復(fù)制代碼 代碼如下:
Id Name State HasMoreData Location
-- ---- ----- ----------- --------
5 Job5 Running True localhost
而在此過程中,我們可以通過get-content d:\temp\timeRecord.txt命令來了解時(shí)間使用情況。也可以用job管理命令如stop-job來停止任務(wù),get-job來觀察任務(wù),receive-job來接收輸出等。
等下等下,不對呀,我們難道不能直接顯示$record嗎?讓我們來試一下。鍵入$record,回車,咦?怎么沒有結(jié)果?
這是因?yàn)镻owerShell這種腳本語言中變量也是有作用范圍(scope)的。腳本中的$record只在腳本中有效,我們在全局(global)范圍內(nèi)當(dāng)然就看不到它啦。可是腳本就不能寫入全局變量了嗎?當(dāng)然可以。我們可以將調(diào)用命令做一點(diǎn)小小的改動,變成. c:\users\grapeot\Monitor.ps1,注意前面的這個(gè)點(diǎn)和空格,以及這里暫時(shí)沒有用start-job而是直接執(zhí)行。等運(yùn)行一會以后按Ctrl+C結(jié)束腳本,鍵入$record看看,結(jié)果出來了吧~這個(gè)". "叫做dot sourcing,利用它我們可以讓腳本或函數(shù)直接讀寫全局變量。當(dāng)然還有一種方法是用set-variable命令加上-scope參數(shù)來讀寫。具體使用方法可以用help set-variable -parameter scope命令查詢。
但是這兩個(gè)特性在后臺job中似乎有點(diǎn)失效。如果用dot sourcing啟動腳本的話這個(gè)job直接就吊死了,狀態(tài)是Running但實(shí)際上得不到運(yùn)行。Microsoft說這是由于叉叉過程造成死鎖搗的鬼。如果用set-variable對全局變量賦值的話還是無法用$record觀察到結(jié)果。據(jù)推測可能是后臺運(yùn)行的會話和當(dāng)前會話是彼此獨(dú)立的,因此沒有辦法共享變量??磥硪朐诤笈_任務(wù)和當(dāng)前會話中傳遞數(shù)據(jù),還只能通過Receive-Job或者臨時(shí)文件了呢。如果各位有什么高招的話還請賜教呀~
呈現(xiàn)與挖掘
一天結(jié)束了,我們也拿到了一個(gè)統(tǒng)計(jì)表,比如
復(fù)制代碼 代碼如下:
Name Value
---- -----
編程 5869
文檔 3217
上網(wǎng) 3078
我們可以利用上篇文章中介紹的腳本把它畫成一個(gè)餅圖,當(dāng)然也可以把每天的記錄保存下來,畫成一周狀態(tài)走勢圖。
你可以做更多…
每個(gè)人都有自己的生活自己的電腦自己的習(xí)慣,根據(jù)自己的需求動手打造自己的工具其實(shí)也是挺有成就感的一件事。而PowerShell很適合作為打造的基礎(chǔ)。除了用電腦監(jiān)控時(shí)間利用情況以外,你當(dāng)然可以做得更多。比如更詳細(xì)的統(tǒng)計(jì)瀏覽器記錄,看自己經(jīng)常去哪些網(wǎng)站;觀看Google Reader的閱讀率統(tǒng)計(jì),退訂那些不必要的Feed;甚至用手機(jī)做一些簡單的工作,比如用計(jì)步器軟件統(tǒng)計(jì)一天運(yùn)動了多少,用GPS軟件統(tǒng)計(jì)自己在上班路上耽擱了多久,看看自己和誰打電話的時(shí)間是不是太長了等等。有時(shí)候很簡單甚至很裸的算法都能帶來神奇的發(fā)現(xiàn)。
其實(shí)這篇文章的目的并不在于炫耀PowerShell怎樣能干,而是想強(qiáng)調(diào)“記錄”這個(gè)習(xí)慣的重要性。只是用PowerShell來實(shí)現(xiàn)相對簡單而已。對于追求完美或者不喜歡命令行的人,當(dāng)然也可以自己寫個(gè)系統(tǒng)服務(wù),效果都是一樣的。
所以說,數(shù)據(jù)就是價(jià)值。讓我們用DIY精神去發(fā)掘生活中與我們擦肩而過的價(jià)值吧!