打印

[分享] POWERSHELL的应用的学习笔记(原著:BRUCE PAYETTE)

本主题被作者加入到个人文集中
用Foreach-Object cmdlet进行处理(笔记:foreach是一种循环)
# B4 g, V; R" O7 V2 g/ D) n- n最后,只是单纯的得到它自己的值。让我们处理一个新的cmdlet可以让你任意的在管道中处理每一个对象。Foreach-Object cmdletd在管道中执行一块语句。! | T% U" R7 C) z
PS (25) > $a = dir | sort -property length -descending |* D6 A* S" q( a8 Z4 D' U
>> select-object -first 1 |; s7 d" n0 S8 F* s
>> foreach-object { $_.DirectoryName }( G" l8 }& {( |( z }3 d) b4 c
>>6 V% ^2 _8 u0 D
PS (26) > $a
6 ?' e+ T* p1 [7 ^C:\files" V5 y9 {6 v+ y
这意味着我们可以得到对象外任意的属性,用Foreach-Object cmdlet作任意的处理信息。
% ~, N$ b! O! N `$ L我们将会显示一个特性,这个例子是计算路径里对象的长度然后加起来。
8 v3 P e8 |" X) z P3 }- r" ~7 o' [PS (27) > $total = 0
- m9 Z; t1 L2 r4 k0 H; |PS (28) > dir | foreach-object {$total += $_.length }4 i2 @' L) a6 D6 Q a! y
PS (29) > $total
& q( S3 P" A" G9 _. _! t( ]308- s, F& R! E G, }
在这个例子中,我们把$total初始化为0,然后加上每个文件的长度,用dir命令输出,最后显示总和。
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

处理其它种类的数据
4 T' F/ H( F* P0 K x: v2 Z
; i& `7 G: h% d3 }学习PowerShell入门的最大的动力是学习解决难题的模式,你可以一遍遍的使用这些模式。举个例子:6 Y1 g) O+ z; ?# Z, ?# h7 ]4 e) y
我们想要查找路径中最大的三个文件之一,命令行可能会像这样的:
5 h% @" l' E4 _ c% g& \1 kPS (1) > dir | sort -desc length | select -first 3
9 o( Z! X) B7 ] Directory: Microsoft.PowerShell.Core\FileSystem::C:\files
* E- Y! u$ e+ R1 e" qMode LastWriteTime Length Name
7 v3 t/ J" l, c9 P- F/ I---- ------------- ------ ----! I9 ^* ?8 d* s2 {& I
-a--- 4/25/2006 10:56 PM 102 c.txt
* P; o! n. r" K9 R5 z-a--- 4/25/2006 10:55 PM 98 a.txt% n1 C! @+ o$ y6 D6 _9 N/ D# {, T
-a--- 4/25/2006 10:54 PM 66 d.txt
4 B! e2 D7 z. H! [3 Q9 i6 ?6 n7 R我们用dir命令来得到文件信息对象的清单,按长度的降序排列来存储它们,然后前面的三个结果来得到
, ~% Z n! N( q6 K/ T$ X/ G) d( o# N& _+ i/ D1 e3 J
最大的三个文件。- q+ I; j3 i# M' q0 {
现在让我们处理一个不同的问题。我们想要查找系统中的三个程序和最大的working set size.命令行会像
4 _5 R' ?, U: [- Z2 m9 ~9 T" P3 U2 a N. E- {* d! b0 z: A' |
下面这样:
! \& Y8 ^; L( dPS (2) > get-process | sort -desc ws | select -first 3
9 N+ m3 u9 _9 nHandles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
( ?! Y, @9 F5 X9 H+ ]+ }------- ------ ----- ----- ----- ------ -- -----------+ x; M$ U& q M" E: Q a
1294 43 51096 81776 367 11.48 3156 OUTLOOK( z7 h, O# P, p: H, n
893 25 55260 73340 196 79.33 5124 iexplore
$ i6 M6 y7 j# V$ E2 Q 2092 64 42676 54080 214 187.23 988 svchost6 Q% M- Y1 N, O
这次我们我们运行Get-Process来得到数据并且用working set排序来代替文件大小。
. V! M |5 Q, d. r" b y5 ~另一方面,该模式被统一为先前的例子。这个命令模式可以被重复的应用,就是一遍又一遍,哈哈.
7 X4 u+ e, e: x举个例子:为了得到Exchange 邮件服务器中最大的三个邮箱,命令会像下边:) }8 A% z( z/ d- I0 a5 Z
get-mailboxstatistics | sort –desc TotalItemSize | select –first 3
' G1 t$ q- O- Y( ]: y( s0 M. ~甚至当我们往后在分析数据中不用特殊的命令而使用其它像WMI的工具,(第十二章有WMI的更详细信息)
4 k/ B! ?: n3 L6 w4 z4 K4 x% F我们也可以应用模型.比如我们想要查找系统中空间最大的三个磁盘,我们需要得到一些WMI的对象3 F e! _& @* E+ j
为了作这个,我们需要从WMI中得到一些数据。不要惊奇,这个命令就是Get-WmiObject命令。现在展! T, f$ ^' x. J0 r# E: O3 x

5 E3 t9 q/ v5 Q3 ^ k9 \9 @: i- d示怎样使用这些命令:
: O# B- r0 R+ m# J+ e* FPS (4) > get-wmiobject win32_logicaldisk |
$ m5 t( e$ N& }: `: l>> sort -desc freespace | select -first 3 |
3 `: R' Q- q1 n4 C! F>> format-table -autosize deviceid, freespace" r. \, \/ ]2 g6 k" u! ]
>>- r5 w4 i/ k( z
deviceid freespace
/ \9 k. J" l. {6 ~' m0 i1 s-------- ---------, b% o! Q" q# l# ^
C: 97778954240
5 P6 z+ G! d$ pT: 31173663232& Y4 Z* _4 h7 M9 ]" R
D: 932118528- X+ ~; u0 X( j6 J( |
模式几乎是完全相同的。Get-WMIObject命令返回了WMI的一种对象。我们把这种对象输入管道中然后( V3 U7 x& l1 b# c" O
* |: @+ h7 w6 ~1 U4 M% g" b. A+ j
用剩余空间属性来排序,然后用Select-Object来展示前三个对象。
8 E' J, C. ]' e# o# ^( b* Q作者笔记:因为这种能力一次次的应用这种命令模式,这本书中很多的例子故意弄的很一般。解决方案
, I6 u6 _1 S) V
! t5 y/ p# _0 @* r! j0 a中的模式都是高亮的,除非是特别的例子。在你理解了基本模式之后,你可以有效的改编他们来解决多7 l t# Y1 l Z0 b+ n# M: ?

9 E% z; l6 {; O9 ^" [6 u9 O& D5 o' N数的难题
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

流控制语句
, k) c$ t+ N3 H" D( T: L/ p5 v管道很棒的。但是有时在你的脚本中需要更多的控制流程.PowerShell有一个有用的脚本流程控制语句,
6 p* Q' c8 x& X' V% N: K6 Y1 Y; h很像while循环和if语句:
" R" X1 N6 @- N6 v; J. p |6 LPS (1) > $i=0
+ e0 x: `* a' m6 [/ ~) w$ y/ sPS (2) > while ($i++ -lt 10) { if ($i % 2) {"$i is odd"}} e! I3 P, }; J: d+ o% f
1 is odd
" i+ f$ c6 ^# J6 p, `* i: l3 is odd
# |- ^) q7 Y. q* s5 M5 is odd
: X! D* x3 Q) y! C6 w, D7 is odd# O* d6 z1 D) {" T* G5 U
9 is odd
, T; l6 D4 M8 N, V$ _5 U* R+ LPS (3) >( v4 S6 q a2 v& @# y
这里,我们用while循环从0数到9。在while循环体中,我们有一个if语句来测试是否真正的数字是odd,然后输出正确的信息。有许多附加的流控制语句。第六篇覆盖了这个特性的完全属性。" {- v6 Q. J4 u5 L' P2 T
这是PowerShell“食谱”的结束,我们轻而易举的遍历了环境的特点和能力。在接下来的篇里,我们将要覆盖我们讨论的每一个元素的细节和更多的东西。
0 Q# b m: h1 ^/ B0 w- |- u1.5总结
( l A6 g, R: r% u9 S这一篇覆盖了什么是PowerShell,它的重点,和为什么。在这篇PowerShell导论中,我们也用简单的例子带来了个快速的浏览。这是我们覆盖的关键点:
6 T. ?, F% h( d9 R! G6 QPowerShell是微软公司新的命令行和脚本环境。3 o; q S" P" S4 k1 c+ e6 c
微软的windows管理模式主要是面向对象,给我们提供了一个命令行脚本的长期入门。
4 E; V6 U0 C/ D1 _+ h4 Z" |PowerShell用了一个.NET对象模型来作键入对象的基础。4 f0 ^+ D$ Q2 K) |' G
在下一篇中,我们看先前展示的每一个语言特性中提供的更多细节。
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

第二篇
: W. z: k1 L. I s8 L) V9 R基础
. j4 F7 [3 \2 ~- }% F8 x2.1命令观念和术语
# m7 [( y1 N+ d2.2语法分析和PowerShell( H3 V1 T0 D2 M
2.3管道和命令6 o, G, o3 Y" w# ~: |$ n
2.4格式化和输出
# j; e. q! W+ q$ {, z, I2.5总结1 x9 _3 t0 F5 i" q+ a& T3 b

# F" w" }: ~: F$ B/ M阅读第一篇时,你看到了PowerShell的历史和原理这些基础知识,你将要把目光注意到PowerShell的细
# ?* F0 d3 X" o+ S+ R; h% u( n4 Q6 f, }
节和它的环境。这一篇覆盖了PowerShell的特性和PowerShell注释器怎样解析它自己的命令行的。
6 o, s7 K L3 K8 p2 {: L3 X他也剖析了命令行自己的大纲。现在的一篇中很多的例子并没有作完全的解释。如果你读到这些例子时8 d! e: A% v' E" n1 L# @, v
u. x) L! v- I% M6 z
不能理解,不要担心---我们将要重新访问这些材料。这一篇中,我们只想覆盖主要材料,下一篇我们将
- U" j+ W. t- d6 N6 y6 g+ R7 Q/ h9 N8 @$ |
要把焦点放在细节上。
! i8 w8 i- \3 Z8 z& Y; W在挖掘PowerShell的内容和原理中,让我们先来捕捉语言的表达式。PowerShell语言像什么呢?鸟类兴) N6 c# K$ Z0 ^, @( H( Y/ Q

4 i- _: L' x0 F" b4 ?; p趣小组已经学会了在成百的特殊的鸟类快速移动的布郎运动区分出来各种鸟类(我们知道,景观学是研0 ^. l% s' `& X- o; ?' \+ r
( s. g' u2 y6 C% E$ s; b
究这一课题的)在理解了他们是怎样作到这一点后,我叫上我的妻子.(我只能识别出一种鸟,就是小鸡
$ m4 p. D9 z2 j, R3 Q( y: d
& b" G# d. ~% Q,烧烤后被我们狼吞虎咽了)鸟类爱好者使用一些被称为G.I.S.S原理的东西。这样代表了鸟类普通的印象6 ~5 x: o, b) g1 b
0 w) c9 b7 n/ ~+ \- Z( [
,大小和形状。这是一种让你挖掘远距一瞥得到的简报的特性。看一下在图像2.1展示的轮廓。图中显示6 ?3 v5 D& W- R- r7 c. E

& y$ i- t1 m3 T, c* @, s了四只鸟的关联号码并用高亮显示每只的特征形状。这为认识每只鸟提供了足够的信息。7 r1 [2 ? o3 G3 c$ Y% T8 h$ y9 p
什么是计算机必须去作的(另外也证明我们不能一个人来完成奇怪的缩写标记)?本颀上,G.I.S.S原理在程序
4 R3 A0 C$ ]3 a" p k& S% K! N: L) q% d
语言中工作的也很出色。全部G.I.S.S的PowerShell语法是它像任何的特殊而不同的C程序语言的降序排列
& ?! S8 H" m/ s2 G% ~+ f' @* u5 t" p, h4 t# C
。变量前面用了美元符号("$")前导标记作区别。
& A$ i+ ~$ b/ Q0 o作者笔记 PowerShell在一些新的地方使用"at"元件("@"),用$_作默认的变量,然后用"&"作函数的呼叫操作* x5 D& E( O r8 A7 ^0 y
3 E) w/ [8 p! C+ w9 t( a6 g
符.这些元素让人们说PowerShell看上去像Perl.实际上,第一,我们用Perl作根语言。第二,语法变化了,
# A9 N9 ^7 H/ X$ G7 l% {
& v+ y. P; e" Q. X, o: ?) |5 {( d( K变的对齐方式更像C#,但是我们保留了这些元素,因为他们工作良好。在Perl的术语中,他们被意味深长$ _. c- a5 |0 s) k0 U! k

% O& ~5 w5 Z9 C的被捐献到了"whipupitude quotient"语言。
5 p; K& I% f; ?5 p, O
实际上,PowerShell语言看起来像PHP.(这像一个平行进化的案例--大意是如此,考虑起来像)。但是要清
5 i5 M! i, l6 N( U
+ M5 `5 M" q \) L! ]1 ~( Q醒;语义上,PowerShell和PHP还有相当的不同。8 q- r) ^. m& ~
这个图像阐述了G.I.S.S原理----一些公共鸟的普通的印象,大小和形状.甚至不需要一需细节,基本的形状
; o! T- i6 _' X2 K9 G
- I( g1 {( @5 ~+ N2 k, q/ t0 H8 h c和大小已经足够让大多数人鉴定出这些鸟了。这个原理也可以在学习程序语言时应用;语言全部开关的
1 ~; h- j" Y0 s8 o% c; j' T1 w8 i: W8 E6 }0 o" g& [. \
一部分也能让你鉴定语言的公共代码参数。
: @9 E; s4 ^$ g6 uPowerShell语言的核心基础是POSIX 1003.2Komshell的程序器。原理上,Perl 的语法也适合一些资深内
! m; ?' F/ R8 g9 P$ j7 ~! | |0 p0 {
容像hash tables.无论如何,作为项目的目标,对C#来对齐PowerShell语法是适合的。不出意外时,在C#
7 i6 D* Q: A: t' I1 j& t4 s1 {2 E3 i( [. @! A: _
和PowerShell中移动代码是很容易实现的。对与主要的数值PowerShell代码作行为揭升时可以移动到C#,) s1 S n& \ D- Z9 q0 i7 i
C#的例子可以容易的转换成PowerShell。第二点很重要,用新语言完成很多的例子后,会更佳。
附件: 您所在的用户组无法下载或查看附件
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

2.1 命令内容和术语
2 t+ f) z( T5 _* S& T1 z0 q0 g和任何种类的新知识一样,PowerShell有它自己的术语,尽管我们试着尽我们所有能力来平衡存在的术语。所以,PowerShell中用的很多的术语和你过去用的一些shells是同一家族的。无论如何,因为PowerShell是一种新的shell,我们建立了很多新的术语并且很多的术语是不同的。在这一段里,我们将要覆盖PowerShell的命令类型和命令语法中的奇怪内容和术语.) E- f% `' F6 ~
2.1.1 命令和cmdlets# c8 I' t0 K$ k0 {( B
命令是其它shell语言中的基本原理部分;那是你输入并得到回应的部分。像我们在前篇里看的,我们演示了下面这个简单的命令:
9 p% q' z) G7 w5 @9 k5 p; h( ccommand –parameter1 –parameter2 argument1 argument2
. l) {0 M; f* ~2 n1 Z4 W图2.2是剖析这个命令的详细图例。这个图例表达出了所有命令的个人元素。
7 M1 r2 j( u/ X- e6 I# w所有的命令都被打散成了命令名,所有的参变量表达了命令,表达了自变量和参变量。
% b. O4 C W! S6 R" [" Z# }图2.2这个图例是一个剖析基本命令的展示。他从命令的名字开始,后面是许多的参变量。这些可以作没有自变量的参数交换,作了参数的规则参数,或者在命令行中对位置参数进行判断的位置参数。
' I. V2 t+ t/ r作者笔记:从程序员的角度,自变量和参变量应该是有很大的差别的。无论如何,如果你用了像Python或Visual Basic之类充许使用关键参数的语言,PowerShell参变量相当于关键字,也相当于数值。$ @+ ] Q& z2 k! X) s' l
命令中的第一个元素是被执行命令的名字。PowerShell解释器看到了他的名字和计算出数值真正的结果。应该明白,这不是运行的命令而是种类,所运行命令的种类。在PowerShell中,有四种不同的命令种类:cmdlets,shell函数命令,脚本命令,本地的windows命令(在下面的章节中,我们将要覆盖不同种类的细节)。接下来没有命令名了,只有更多的参变量和自变量。参数简短的开始,后面跟上了参数名。从别的方面来说,一个自变量的数值将要和特殊的参数进行联合和捆绑,让我们看下面的例子:+ z. }* B, C. n M$ ^2 }- {
PS (1) > write-output -inputobject Hello# u4 M9 ?6 ^" o" \" T7 t N
Hello: k9 Y; Q7 l; @( s, F( b
这个例子中,命令是输出,参数是输入,自变量是hello.
7 Q. {9 c0 c0 j, J, \% K7 S. L5 Q在图2.1中提及的位置参数是什么呢?当一个命令在建立时,甚至在它自己的参数名丢失时,命令的作者信息也可以为充许PowerShll挖掘绑定的和联合的参数提供信息.上个例子,定义输出命令后,第一个参数是输入。这让我们写道:
7 G8 w* G# o Z: c2 NPS (2) > write-output Hello k: B3 h- |) x0 k8 o
Hello
" a0 b5 v: o3 s3 ?. Z$ F这样,-inputobject的说明被人替代了。这种能表达了所有输出的PowerShell解释器被称为参数绑定。事实上,参数绑定是聪明的-----它让你不需要说明参数的全名也足够来区分参数独一无二的区别.这意味着你可以写下下面这些东西:
/ H6 O) `! ~5 p) o5 P) EPS (3) > write-output -input Hello1 N+ P/ `, Q- h7 f/ v- ~
Hello
& D4 ]+ O2 N4 R7 G3 wPS (4) > write-output -IN Hello
$ \9 P5 I8 ^: r/ n# O5 A# lHello
Y9 n9 }' c- j& Q& C6 uPS (5) > write-output -i Hello
, E/ \2 ?7 V' K6 kHello( z& \! _0 O$ Y' h
大小写字母对参数绑定并不重要。那么参数绑定还有什么特征呢?它主管着怎样比较参数和自变量类型。PowerShell是个基于对象的shell,PowerShell是一种类型。为了使PowerShell无缝的工作,PowerShell用一个清晰,复杂的类型转化系统来合并事物,这是第三篇的课题。当你在命令行中输入一条命令时,其实是输入法些字符串。如果命令需求和对象类型有不同,它们之间究竟发生了什么呢?参数捆绑器用类型转换来试着把字符串转成参数的真正类型。这是个简单的例子。让我们用Get-Process命令来处理process ID 0.代替现在的数字零,我们用强制引用来把参数变成字符串。这意味着--id 参数,本来用数字表示的,现在用字符串代替。
) ?' E" S2 }7 s f8 ^) } bPS (7) > get-process -id "0"4 M/ R X6 C' c% d1 L% n' ~
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
! p w. S9 M* J y6 V------- ------ ----- ----- ----- ------ -- -----------
! B; q! o. p* A% [ e 0 0 0 28 0 0 Idle6 D0 B9 l+ p; T8 c y
当试着来运行这个命令时,参数绑定器检测到--id需要一个数字,而不是字符串,于是,它把字符串"0"试着转换成数字。如果这样成功了,命令会继续,就像前面的例子展示的结果。转换失败会发生什么呢?让我们试试:
& v8 A6 j+ Y% G }PS (8) > get-process -id abc
! p2 d# A8 B' D! U$ Y! GGet-Process : Cannot bind parameter 'Id'. Cannot convert value "abc"
% R. ]: h5 P" i+ }9 B* \to type "System.Int32". Error: "Input string was not in a correct fo* W {$ r9 |) [. @
rmat."6 L! a0 r, @/ N4 [$ q, ]' ^8 h
At line:1 char:16
. x0 N( l" C' Y' U. u+ get-process -id <<<< abc/ v f6 V. z. g! U; _
PS (9) >) q4 H2 @3 v T$ B2 F
我们得到错误的信息,类型转换失败了。在第三篇讨论类型时将会讨论更多细节。在我们介绍引用记号的使用时,让我们看一个其它的例子.。在使用pass to命令工作时,参数会发生什么呢?这时,引用诞生了。让我们用输出语句来打印字符串"-inputobject".
' X$ C. }+ @& I. m0 @. o) xPS (1) > write-output -inputobject "-inputobject"
& {, ~- o/ m7 n-inputobject
, E. ~" g# B% a( w x& p6 v; M按照这个要求工作时,我们可以简单的输入:
# v9 `- l. `6 s( W c% Q& EPS (2) > write-output "-inputobject"
7 j: z4 P6 K, }, J& z5 \. }! x-inputobject& s* ?* }/ B* f! b2 D+ b! t2 M0 X% I
引用保存了参数绑定中的参数来处理引用字符串。
( P8 U3 V5 v( c( w+ X4 |5 U作者笔记:其它的,两个连字符像"--"作后置参数是较少使用的。这个序列之后将要看作一个争论的东西,即使它看起来像参数。举个例子,使用"--"我们可以不用引用写出字符串-inputobject:" t; A4 h" M% @; c& Y) A
PS (3) > write-output -- -inputobject
+ ^5 F$ [6 C6 S' b- Y, h2 \ -inputobject; ]6 ^2 b: G8 Z

7 j* a+ R& C5 ]; R: S(未完)
附件: 您所在的用户组无法下载或查看附件
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

看着看着有一点点云里雾里了!呵呵 不过我相信通过我的努力,终有一天会拿下POWERSHELL!
风往哪吹 一路向北

TOP

"--"序列告诉参数绑定是如何处理自变量的,甚至在它本身像参数的时候。这种转化被unix shells采用并' |* M9 t2 o+ Z1 p6 U$ m7 @! L
7 {0 c" c0 E+ L l& Q
且符合POSIX Shell的标准化,也是特殊的工具。
% n' }2 ^1 q% [/ w4 O基本命令的最后一个元素是交换参数。这种参数不需要自变量。他们经常偶尔有自变量,偶尔没有自变9 F* W! L$ a( @) i$ W- q# S% P7 W
+ t" Q# f) v$ {! I4 W. K: j3 H
量(显然它不能有这个地位).最好的例子应当是dir命令的-recurse(递归)参数,这个开关告诉dir命令# F) X! I2 r5 q a- [8 \
+ u# R/ s7 k/ t7 Q( e" V- R
来把特殊路径和它的子路径里的文件显示出来。
9 o4 M, M9 g$ b- w* P* yPS (1) > dir -recurse -filter c*d.exe c:\windows
5 L$ z. c2 N2 o* Y Directory: Microsoft.PowerShell.Core\FileSystem::C:\windows\) O7 Q4 ?8 M& A
system322 M( A6 y' m# e; I# j7 g/ n
Mode LastWriteTime Length Name
' e0 w8 F$ t4 q. W& t---- ------------- ------ ----
; W7 U9 G; ^! n5 T-a--- 8/10/2004 12:00 PM 102912 clipbrd.exe# D7 z" ?3 Y n
-a--- 8/10/2004 12:00 PM 388608 cmd.exe
' Z: C. E: d1 @: F作者笔记:虽然,这个交换参数几乎总是不带参数的,它也可能带特殊的参数。这章,我们将要把何时
+ ?, I: Q4 a* p. Z
4 z' e0 W: n. s( a, l3 `( ]) r5 ^和为什么你可以这么作保存在脚本中(shell函数和脚本需要时间来表达进一步的特性,所以当时间到来前
) V# Q' g, _- K
* C$ J+ ]+ i2 P6 o3 W/ u7 m: F3 y我们带给你着悬念).
" G g1 F I0 h2 R; y {现在,我们已经谈论了命令行的基本结构,让我们复习一下PowerShell支持的输入命令。
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

2.1.2 命令种类
. H$ O* o: C) N. R4 e; c我们早先提到过,PowerShell有四种命令:cmdlets,函数,脚本,本地Win32可执行文件。第一类命令是
h+ X. k/ ?) k% D$ u
2 h s8 H0 G# V% U6 s% W. m) Q- bcmdlet(发音是"ommmand-let").Cmdlet是PowerShell环境中的一种特殊术语。Cmdlets来源于PowerShell7 q3 H9 |& ?$ z% x9 |, M. y
+ Z9 p9 d2 n6 Z: s. C |8 V7 K0 m/ ?
语言开发工具(SDK)的cmdlet基类,是一种.NET类的工具。/ h( F6 q/ h0 n" P7 d
笔记:建立cmdlets是一种开发任务,它需要PowerShell SDK.SDK可以从MICROSOFT免费下载,包括了很多
; @) ?8 _# j# v1 E
* Y" O' l/ Q' P免费文档和很多例子。无论如何,Windows PowerShell in Action 这本书的目标是指导你来有效的使用
6 {3 g# K5 b6 E3 F% r2 B
o$ r0 h% E1 z8 ZPowerShell环境中的脚本,所以本书中不会过多的提及SDK.5 B8 Q1 b2 d) k! N
当脚本运行时,这类命令被编译成dll并且被载入PowerShell进程.编译代码被插入进程后,执行时变得更
% J$ c4 X ]: r6 O# P; k( e0 j8 z# \1 H4 N j3 D0 A
有效。Cmdlets总是从动名词中命名,应用了特殊的动词和从特殊的名词对象中操作。在传统的脚本中,
) M4 S, Z8 g# ~8 H3 R
+ M' t1 q$ T# YCmdlets更像经常被称为内置命令的命令。在PowerShell中,任何人可以在任何时候增加cmdlet,可是这
" ]( x, z/ i& M' R; z2 o
. q% r0 o( }7 o$ n1 X并不意味着cmdlet是内置命令中特殊的类。Cmdlets在PowerShell1中提供了最好的支持:全部的在线帮& o: w. S8 s2 a. G5 U" a z1 c* o4 l

" \1 l5 O" v8 ]4 u( Q助支持,本地化的,和最好的参数绑定支持。0 Y" o# Z- P1 w# ^
X# r0 E# l, |
在清单2.1中,你可以看到简单的cmdlet的C#源代码。这个cmdlet只是把输入拷贝到它的输出中,如果参
$ W6 g9 C% M7 k5 \6 H+ M U8 V! j; r/ O b8 u2 Z8 K9 A
数1是个特例,那么自变量将成为输出自符串的前置。这个例子展示了cmdlet的基本结构。列表中有两个
' e# z: h/ X* M/ m
7 B6 ?; x' p* O. X1 S重要的事要注意。* a" m: ]7 P5 ?# _( j) C
(未完)
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

第一点,参数声明用了参数属性。这个信息被实时的用来决定cmdlet的参数。cmdlet的作者们不用为参数分析写任何的代码;就实时的关注了参数分析的运行。. W7 \* {+ ^" R5 I: A
要记住的另一件事是:管道行的变量其实是真正的注释。这意味着参数可以用从管道行里的注释来重新填充他们(我们将要在这篇后面的部分来讨论这层含意。)% }8 F; D7 `$ k
3 Y; L) P! o# s5 C T6 S- F
[ 本帖最后由 kenknigh 于 2007-6-2 23:02 编辑 ]
附件: 您所在的用户组无法下载或查看附件
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

下一种类型的命令是函数.这是一种当解释器运行时存在于内存中的被命名的一块PowerShell脚本代码.
/ i2 Q6 G% W% `: G) [从出口处退出.(在第七篇中有详细的信息来介绍怎么把函数载入进环境中).函数是定义一次后,就能被解析的用户自定义代码.这些语法表达式被保留了,所以不需要每次使用时都进行分析.函数可以像cmdlets一样被命名为参数,但是在PowerShell的第一个版本中,没有完备的参数说明能力.在清单2.2,第四行中的这段脚本是从进程关键字开始的,符合在清单2.1中的程序记录方法.这允许函数和cmdlets拥有同样的流行为.(在本篇2.3.1中有关于流的更详细的信息).& |$ O& ~4 T" s# t
清单2.2
/ \5 ~: {# H" L) {. J: Qfunction Write-InputObject
' e# o s& O$ i0 q7 ^- m1 j- e{$ j3 T( w5 x- x! A
param($Parameter1)$ u8 ]; ~$ l5 ?3 ]! ^( p
process {
1 J }. d4 E7 y( P9 ^- K) z if ($Parameter1)0 C" G1 s( @# ]* O1 g" y# T
{ G# v5 S# n, E' y
"$Parameter1:$_"
% ^; E) y' y& _ } else {! R" P1 A4 t# E* ^3 D7 N
"$_") p! ^- w" g' X* H4 x1 h/ G9 N
}0 s; f6 A7 u- b% t8 A8 s2 W% Q. G7 J
}4 P2 s3 `6 V3 H1 Y6 n1 `+ e9 h7 C9 ?
一种脚本命令也是一块PowerShell的代码存在于有一个.ps1扩展名的文件中.在PoweShell 1.0版本中,这些脚本文件在他们运行时重新载入和解析,所以他们总是比函数运行时慢一些.在术语中,parameter capabilities,shell function commands,script commands是一致的.: f1 x( U' S6 g5 t7 o3 J
最后一种命令被称为本地命令,这些扩展程序(也是经典的可执行文件)可以在操作系统中执行.8 ^6 t) R, N0 _5 V, v
作者笔记:为这种事选择名称是困难的事,本地命令的术语多少听起来有点怪.我们原来把扩展命
) }: t3 r: M# |( O; A: ~+ _令称为"继承命令",然而,继承所回馈的更感觉成了否定术语.另一方面,简单的把他们称为可执行文件真得不很适合,因为这类文件也包括了cmd.exe文件,批处理文件.最后,我们还是觉得本地命令有充分的特色.
' ]2 R1 j- U1 r运行了本地命令之后,就意味着该命令建立了整的新的进程,本地命令是最缓慢的命令类型。
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

第一条,所有参数将要用参数属性进行声明,PowerShell实时的用此项信息来自动决定cmdlet的参数。cmdlet使用者们不必要为参数语法提供任何的代码。他们实时的关心cmdlet是如何运转的。另一条,
4 d9 u* ^$ \' P f- s: `4 sValueFromPipeline是真正的计数法;这意味着参数可以通过管道行运行数值。(我们将要在本章以后的部分中谈论这些)
5 {6 {! b+ J! ~( m
2 H. _. C# D8 d" [5 d& W: @9 W
4 i$ f* D- Z8 c& d. e
, N! \! B1 g0 b8 h下一种类型的命令是函数.这是一种当解释器运行时存在于内存中的被命名的一块PowerShell脚本代码.
6 m f6 U! m% W从出口处退出.(在第七篇中有详细的信息来介绍怎么把函数载入进环境中).函数是定义一次后,就能被解析的用户自定义代码.这些语法表达式被保留了,所以不需要每次使用时都进行分析.函数可以像cmdlets一样被命名为参数,但是在PowerShell的第一个版本中,没有完备的参数说明能力.在清单2.2,第四行中的这段脚本是从进程关键字开始的,符合在清单2.1中的程序记录方法.这允许函数和cmdlets拥有同样的流行为.(在本篇2.3.1中有关于流的更详细的信息).
1 o ^4 X0 N4 G. Q清单2.2- u* V8 N/ v! O9 Q5 H$ d# X
function Write-InputObject
* w% u0 w! R! U8 ^ {( z{' z0 _0 ?) Q. Y& c& P K& G3 z
param($Parameter1)- i1 _; O) H! a0 M% u
process {9 e- B5 u: i3 `# Q9 _# K3 t. \3 s
if ($Parameter1): `; Z) E! P9 e M0 I' o; |- a
{
) ]8 X4 e+ K$ Z "$Parameter1:$_"+ N2 e$ _5 o7 B, V& g" n$ J' W
} else {
! X, v3 B) m- J* x' ^3 k. F "$_"+ Q8 |7 e( y6 O8 u2 i, e' H9 R9 Q5 u
}
3 v+ C- w% W& l1 R+ ]0 ~}
& X3 D* H6 H6 `一种脚本命令也是一块PowerShell的代码存在于有一个.ps1扩展名的文件中.在PoweShell 1.0版本中,这些脚本文件在他们运行时重新载入和解析,所以他们总是比函数运行时慢一些.在术语中,parameter capabilities,shell function commands,script commands是一致的.! ]7 e! ?% j; ?! u
最后一种命令被称为本地命令,这些扩展程序(也是经典的可执行文件)可以在操作系统中执行.
( ^# ] [6 n2 k0 X作者笔记:为这种事选择名称是困难的事,本地命令的术语多少听起来有点怪.我们原来把扩展命
: S. f4 s3 a% a" d. x2 U令称为"继承命令",然而,继承所回馈的更感觉成了否定术语.另一方面,简单的把他们称为可执行文件真得不很适合,因为这类文件也包括了cmd.exe文件,批处理文件.最后,我们还是觉得本地命令有充分的特色.: A7 x' T& H8 j! Q0 H. u
运行了本地命令之后,就意味着该命令建立了整的新的进程,本地命令是最缓慢的命令类型。
3 d6 `$ a6 B ]5 F
$ ?7 ^9 N3 ?# ]: Q, ?+ q4 `同时,本地命令用他们自己的参数进程而不用比较其它类型的语法。当然,本地命令覆盖了在windows计算机上能运行的任何事,所有,有广阔多样的行为。有个最大的问题是:PowerShell在等待命令结束前它保持着运行。举个例子,在命令行下开始一个文本文档。
$ O- f. V/ _$ ^3 DPS (1) > .\foo.txt* O5 M( f2 N. A' L( i+ l4 C
PS (2) >
. ?+ K% x) R9 X8 w- g你很快能得到命令行的回馈,你默认的文本编辑器弹出来了(或者默认是notepad.exe)。运行的程序被作为windows环境的一部分而被定义的文件关联决定。* o) H# r- s r6 [0 t
笔记:在PowerShell中,和cmd.exe不同,如果不在当前路径中,你需要一个./或.\的前置命令。这是PowerShell的“安全设计”哲学的一部分。这一条安全特性被采用以阻止特洛伊木马攻击,当用户被引诱进一个目录然后运行像notepad.exe之类无害的命令。它可以替代直接运行系统中的notepad.exe,它阻止攻击者放在路径中的被命名为notepad.exe的恶意程序运行。在第13篇中,覆盖了PowerShell环境中的详细的安全特性。
1 G: V- G% |2 c0 T& ~) K所以你怎么详细清楚的说明编辑器呢?$ r& P/ s5 h g: V
PS (2) > notepad foo.txt
$ E2 O) w, a. UPS (3) >$ g8 X/ F5 y7 }1 d; M
同样的事发生了----命令迅速的返回了。但是你在管道行中运行命令的过程中会发生什么呢?
; w. |- D+ S$ ^0 Z0 q' H# d/ cPS (3) > notepad foo.txt | sort4 ]6 e# R3 n7 {1 {' o# `
<exit notepad>
! o" K f) z1 U8 r5 d9 I4 cPS (4) >
9 s T. ^! y- w G4 ]+ B现在,PowerShell在提示符返回前等待着命令退出。这可以为你在编辑器的脚本中作一些进程来插入一些图片提供便利。
1 s# @5 X7 M3 V6 w7 j" `最后,让我们运行edit.com程序。这是一种windows自带的从DOS 4.0后出现的基于古老控制台的全屏编辑器(当然,它也在其它的控制台编辑器处工作--vi,emacs......)- y$ p2 h, s( s- q; W2 x, ^3 X
PS (6) > edit.com ./foo.txt
2 f0 W$ s+ n- y0 l8 W$ {PS (7) >, H2 d/ t M- g/ u
和你期待的一样,编辑器运行了,接管了控制台窗口。你可以编辑文件然后退出编辑器返回PowerShell,这样,一切正常和合乎期待。你能看到,本地命令的行为依赖于本地命令的类型,和管道行一起出现。
. }. J0 M F0 B6 D1 G8 D现在让我们来看所有的PowerShell命令类型,让我们再返回PowrShell语法。
- v! c( M- V) |! V2.1.3 别名和有弹性的语法! E. i; [, p4 n" }$ T
我们还没有真的谈论过别名也没有谈过他们是怎样在PowerShell中完成有弹性的语法的。这个内容在PowerShell环境中很重要,我们需要为这花费一段时间。( T1 k% C- z+ }# F2 e6 o, U
cmdlet的动名词语法,既规则,也冗长。同时你也可以注意到,我们用的更多的例子既像dir也像type.
# N* e2 ^) M) m& N& j5 U别名是一种隐藏所有这些的诡计。dir命令是get-childitem,type是get-content.实际上,你可以用get-command命令来看这些。
; f, w1 P( d1 Z/ E$ NPS (1) > get-command dir
) ^6 a2 v# i" I9 Q. l" U' zCommandType Name Definition
3 e4 ~# L, l# R8 J6 s( N% s8 j----------- ---- ----------
; ]* S6 `0 q# I) W9 r) _+ k; rAlias dir Get-ChildItem
5 }3 b, V% L3 J' ^- {上面告诉你get-childitem的别名。想得到get-childitem命令的信息,你可以用:
: c: ]. S5 F5 X4 p& T8 XPS (2) > get-command get-childitem
! r/ e/ q9 z4 o/ S9 |5 Q% GCommandType Name Definition
* C( [8 Z3 O+ C1 ~----------- ---- ----------, x: p( P6 D0 y$ k. Q# o
Cmdlet Get-ChildItem Get-ChildItem [[-P...
0 N4 D' g: @; J; L可以截断控制台窗口的宽度信息。为了观看所有的信息,可以从管道输出get-command到fl:% M$ C u4 z( G: [
PS (3) > get-command get-childitem | fl
6 q% G* S- t8 l/ B t4 g" b; Z! lName : Get-ChildItem* |, A" v9 S8 q+ j
CommandType : Cmdlet h6 Y/ z! L/ x, `. J
Definition : Get-ChildItem [[-Path] <String[]>] [[-Filter]
# v0 I9 `( V, l' J8 B9 d <String>] [-Include <String[]>] [-Exclude <S
5 X! E8 r% S C tring[]>] [-Recurse] [-Force] [-Name] [-Verbo3 q0 r6 _7 t# @- C
se] [-Debug] [-ErrorAction <ActionPreference>2 b: d1 D/ P N1 |5 P1 v2 f
] [-ErrorVariable <String>] [-OutVariable <St
) u5 u( W5 _1 u5 }3 h ring>] [-OutBuffer <Int32>]/ O; V6 U# k3 }4 M. b& [! E
Get-ChildItem [-LiteralPath] <String[]> [[-Fi
: B) [1 j3 X/ y lter] <String>] [-Include <String[]>] [-Exclu- e% h0 j- v$ r) G( t, P, f
de <String[]>] [-Recurse] [-Force] [-Name] [-
4 Y8 @- N0 V7 g; T% _ Verbose] [-Debug] [-ErrorAction <ActionPrefer& r/ g6 c/ R/ q9 A- I/ A
ence>] [-ErrorVariable <String>] [-OutVariabl- w% O2 E& P/ B7 `/ {
e <String>] [-OutBuffer <Int32>]
* A8 {, }1 \" n6 }- kPath :+ _2 y8 G% i8 a& `1 \ k
AssemblyInfo :+ I% F! f/ F0 U& U3 }4 n& }4 B
DLL : C:\WINDOWS\assembly\GAC_MSIL\Microsoft.PowerS
, B) P* L! L5 h* N& C- S8 \) \* u hell.Commands.Management\1.0.0.0__31bf3856ad3
# L4 o. |, ]) s- s 64e35\Microsoft.PowerShell.Commands.Managemen
: u+ `! R8 J7 ]9 U/ x1 [" i t.dll+ f" `# z* e% ]- B7 v4 i+ W
HelpFile : Microsoft.PowerShell.Commands.Management.dll-, |8 s7 P# i5 L/ e) I% m& _2 i
Help.xml$ s4 q: C, M( r& U) \. E
ParameterSets : {Items, LiteralItems}3 ~7 }. I( M: J% }* a
ImplementingType : Microsoft.PowerShell.Commands.GetChildItemCom
+ V" U4 |. ^! `6 |8 [2 z4 D mand
. t9 w+ s* t: [# H+ Z- U; r4 xVerb : Get4 D! e! U+ T5 E
Noun : ChildItem
4 `/ F( L! C, u+ }, M: w/ w& U1 W, b这些展示给你这个cmdlet的全部的信息。但是----什么是fl 命令?再一次我们用get-command来看它:
* s0 ?0 _& W9 E7 ~% D" _PS (4) > get-command fl0 |6 }, o. N# x
CommandType Name Definition; @8 Y9 C4 J7 Z) |5 ]
----------- ---- ----------1 G! @$ B" T. t# z2 [
Alias fl Format-List
- U7 l5 c& b; K, JPowerShell带来了大量的预先设置的别名。有两种基本类型的别名---过渡的别名和方便的别名。过渡的别名意味着一种把PowerShell命令映射到人们使用其它shell时的命令,特殊的像cmd.exe和unix shells.
$ h# y9 }8 i) i. {& I在cmd.exe用户中,PowerShell定义了dir,type,copy,之类的命令。在UNIX用户中,PowerShell定义了ls,cat,cp之类的命令。这些别名充许新的用户立刻使用基本等级的函数。
9 F. H: c' k. j) E# H9 ~% a另一种别名被称为方便的别名。
) r% O( `( v4 n2 Q这些别名起源于cmdlets要映射的名称。所以get-command可写为gcm,get-childitem成了gci,invoke-item变成了ii,很多很多。在被定义的别名清单中,只在命令行中输入get-alias。你可以使用set-alias command(这是设置别名的方法)来定义自己的别名。
* x) x9 f0 a [( d% {$ V作者的笔记:在PowerShell的第一个版本中,别名只被限制成别名命令名。不像别的系统如同ksh,bash,zsh,PowerShell别名不能代表参数。计划在下一个发行版中补充进这项功能。在第一个版本中,如果你想作一些比翻译简单的命令名更机智的活,你将不得不使用shell函数或者脚本。
: d3 h* [# R' ~" R. U0 Y7 H这又好又棒,但是为什么这么有弹性呢?欢迎问这个问题!这个概念中,PowerShell可以在需要时和描述时适当的变得简洁一些。这个语法可以作简洁的简单案例也可以被伸展作得像一个有弹性的带子这类大的难题。(笔记:也许是指以简洁的语言为基础,完成难题吧)这在PowerShell中很重要特别是命令行工具和在脚本语言中。在巨大多数的“脚本”中。你们将要用PowerShell完成不超过太多行长度的脚本。换句话说,在命令行下输入后,他们将要成为一个字符串或命令,然后,输入部分就不需要再出现了。受这个因素影响,在这个环境中,语法变得更简洁。这是别名中,像fl一样的来历---他们充许你写简洁的命令行。在写脚本的时候,无论如何,最好还是使用命令的长文件名。这是因为不久或已后,你将不得不面对你自己写的脚本(或者一些其它错误的东西)。你能看懂像下面的这些东西吗?. }4 g4 ?1 d9 a4 f' n
gcm|?{$_.parametersets.Count -gt 3}|fl name4 U ~5 I+ p4 Q7 x/ X
或者这个?' b* V1 o6 }! O1 s
get-command |
& M0 b& I6 E! ]! bwhere-object {$_.parametersets.count -gt 3} |
) F8 Q/ u3 K5 t7 ~; `6 eformat-list name
3 j- {% T; y1 R9 q/ ^8 B作者笔记:PowerShell中很多命令各自有两个或更多的的名字。一些人认为这并不牢靠----他们提出只要有一种方法来作这事就行了。实际上,只有一个方法达成目标这个原理在PowerShell中也是正确的,只是有一个重要的变更:我们想要在每一个场景或形势中得到一个最好的方法作事情。作为基础,这是计算机谈论时很常见;最简小的,所有的一切都只是一串的比特。实际上,你从单比特到建立起了合适的,符合自已需要的解决方案。沿着这种方法,你建立了一个可以重用来解决其它难题的中等大小的组件.这适合PowerShell的应用:这一组件系列有不同的复杂等级来规划一个广阔范围的类.举个例子,难题中并不总是钉子,所以使用更多的工具而不仅是锤子就是个好主意,即使需要进行更多的学习,我们还要使用除锤子之外的工具.: N( I" R8 r* U: E

7 m, ~7 m: g* b# H9 z f u0 L+ t现在我们谈到了命令在进程中工作的核心,下一步,让我们全方位的来看一下PowerShell语言进程.
1 [6 [7 D$ f9 C: I) B* }7 q8 S% p1 N6 [$ }3 @+ ?8 B
[ 本帖最后由 kenknigh 于 2007-5-30 20:45 编辑 ]
附件: 您所在的用户组无法下载或查看附件
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

2.2 语法和PowerShell" H+ D$ {% [/ t- D; D {- P! B
在这一段中,,我们将要谈到PowerShell的脚本是怎样分析的细节.在PowerShell解释器能够执行你输入的命令之前,它先分析文本命令然后把他转换成计算机可执行的东西.更正式的说法,解释器的进程把人类可阅读的源代码转变成计算机可以理解的形式.这是一个计算机科学的领域,它真正的反应了计算机和科学两个单词.科学真正的意味着正式的语言理论,也是一个数学的分支.作为数学,讨论它通常需要收集些希腊字母.这里,我们将要使事情变得更简单.
* C* _4 b) F) s* n; W4 r一些脚本片断被标记赋予器打散来代表各种记号(或者,如果你想作的更专业,可以成为字典分析员)。一个记号是程序语言中一种元件的类型,例如number,keyword,variable.在文本被打乱成流记号后,这些记号被处理进结构中进行句法分析。流记号被处理成符合语言的语法规则。在普通的语言中,这个处理是简单的---一个记号总是有一个相同的意思。一个数字的排序永远是数字,一个表达式永远是表达式。
5 G9 t4 L. S: I* c6 j排序的例子* T- C7 ^2 I- m% H z" g! [5 `
2+2' z# d0 r1 Q/ J3 G% |, a. t3 F
总是一个加法的表达式,HELLO WORLD是一个常量字符串。不幸的是,这并不符合shell语言的所有情况。有时,你不能在上下文之外建立记号。在下一部分,我们将要为为什么和PowerShell解释器怎样分析语法展示更多的细节。
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

2.2.1 PowerShell的语法分析
. X9 o7 O% c' }- ^, u6 B8 ^8 }+ vPowerShell作为一个成功的shell,它不需要每件事都进行引用。如果需要用户作频繁的输入,PowerShell可能会失败。
; a' d# J+ A$ V n" ^# X: G {" h* ocd ".."- J& s$ m+ X0 t. m, Q8 }
或者
~7 `6 L! I8 [: K" G- O+ x3 Acopy "foo.txt" "bar.txt"
0 q; ^9 T0 x) V0 |' L另一方面,人们对表达式自己如何工作有一个特殊的设计:
* ]) g: E3 V: H- \* {2
$ {. f4 O: R% ?3 E数字2,不是字符串"2".所以,PowerShell有一些兼容性的语法规则。后面的三部分将要谈到这些规则。我们将要谈论怎样引用句柄,两个主要的语法模式,在新行之前和语句结束时的特殊规则。
" F, b: C" r; W2.2.2 引用
+ o* J ]. P( Z2 v7 H: v% W引用被机械的用来把PowerShell解释器中的奇怪意思的记号转变成奇怪的字符串数值。举个例子,write-output cmdlet有个-InputObject参数。但是我们如何真正的应用-inputObject这个参数呢?在作这个时,我们需要先引用它;用单引号,双引号包括它。就象下面这样:3 A3 f* t w! [% h0 ~3 J& H
PS (2) > write-output '-inputobject'
2 a& ~2 O* e* f+ c& c-inputobject
8 F1 I6 m3 C* _' s9 ?8 s如果我们不引用参数,会发生什么事情呢?让我们看看:0 ^6 V; T& |1 S/ I% B5 a8 k
PS (3) > write-output -inputobject; B- v$ w7 ? \3 v$ {' o" J
Write-Output : Missing an argument for parameter 'InputObject'.- J r& y9 G `! |8 P
Specify a parameter of type 'System.Management.Automation.PSObje
) C; S! U( f+ r' Tct[]' and try again.# l7 F9 a* R6 a
At line:1 char:25 H! k; w' o( J& g3 u
+ write-output -inputobject <<<<
m5 g2 ?' e G& n4 cPS (4) >
6 S! y* C) I7 s" e0 Z6 f! kPowerShell支持了几个引用的表单,每个都有不同的意思或语义。把整个有序的字符们用单引号括进去,把他们当成了简单的字符串。这样,你可以处理有一些空格的文件路径。举个例子,如果你想进入带着空格的路径,你可以作下面的事:8 S) a, }, Y6 N/ W M4 r) r# t8 ]/ F
PS (4) > cd 'c:\program files'5 E% W7 K- l, b
PS (5) > pwd7 i0 A8 x% Q3 d2 z
Path
7 F$ S/ s4 |+ Y! R( B----1 Z% s+ I/ T8 N7 a6 q7 x
C:\Program Files
1 z+ p- Q* ~, b+ S3 ^+ E# A2 Y小帖士:你可以输入 cd "c:\pr*es"然后用TAB补完:)
! s8 e: ]* `( f6 \如果不用引号引用会发生什么事呢,看下面的例子:" o3 ]9 ]4 k* X: A. }+ D& |
PS (6) > cd c:\program files
) D) d+ U7 ?& P6 j" H( ZSet-Location : A parameter cannot be found that matches paramete
9 O V! a) L1 K0 O( n" q$ cr name 'files'.# t4 q/ t; ]: |# t
At line:1 char:39 S5 a2 P" E; v( t4 g, m8 b2 E
+ cd <<<< c:\program files 9 f" Y0 b3 w2 x J
如果我们不用引用,我们收到了一个错误来解释意料之外的参数命令因为"c:\program" 和 "files"被分离成了两个错误的记号。# T. e* m9 o' Z7 B! [# A
笔记:注意到错误信息报道了cmdlet的名字,而不是报道被用的别名。你可以看到运行时真正发生了什么。"定位信息"在另一方面展示给你输入的文本所以你可以看到你输入的别名。! t V1 c# U8 s9 K
前面的例子中我们表达了开放引用,现在,比较引用成为我们将要面对的难题。当你想要引用一个简单字符时增加了一个问题。你可以使用后引号( ` )字符来作这个(后引号在最左上面的键,在ESCAPE后面)
/ f8 d) p4 ?( n5 t8 iPS (6) > cd c:\program` files$ }! \; g5 W7 x- }( d8 u: h+ y$ i
PS (7) > pwd! @4 C8 [. N( p0 C: V
Path ]4 X4 l& {0 i, E
----
, L( D: \8 W; [' m% }/ gC:\Program Files8 w2 ^5 }) c0 v% v0 F3 W
后引号,或backtick(` ),因为它易于被呼叫,我们将要在这部分对很多的用法进行测试。现在让我们看看对比引用其它的形式:双引号。我们再一次用我们喜欢的例子。
b2 @ N5 E+ M- ~: ?PS (8) > cd "c:\program files"
' W. ~5 L' B& }; B0 J6 _PS (9) > pwd5 }' N) k7 x, b5 g9 S. }0 H8 w
Path+ S6 o/ j$ o7 C; n0 ^5 S
----* c* W8 C3 ]* [, W P( q
C:\Program Files
, A; `0 ]# T9 z( _这和单引号的例子非常像,那么有什么区别呢?在双引号引用中,变量已经被扩展了。换句话说,如果字符串包含一个从"$"开始的变量参考,它可以用存储在变量里字符串表达式来重置它们。让我们来看看这个例子,一开始,把字符串"files"分配给变量$v:
( J; s# N b/ b8 b) r$ KPS (10) > $v = "files"
. q5 U* l% a3 o. T/ u0 O现在,让我们参考有双引号的字符串中的变量 :0 J, R: Q4 S3 E/ }
PS (11) > cd "c:\program $v"& q7 \: ^/ l- V/ F
PS (12) > pwd" D! F8 x; x4 P
Path5 x) T4 K& u" L. S
----4 Z- p, B# j! V' T( `6 ]
C:\Program Files# O$ j, [, x( i
CD过程成功的完成了然后进入了我们希望的真正的路径。如果我们用单引号会发生什么呢?
* C5 P0 `+ \1 s4 dPS (13) > cd 'c:\program $v'
5 s, r6 v0 I( o/ y3 f1 X5 w' o6 y, o1 \set-location : Cannot find path 'C:\program $v' because it does7 P( N# X1 w- K" J$ w- f
not exist.
/ y1 l/ b7 C& e2 h, ZAt line:1 char:3
/ x" l3 ?. P1 [6 G& u# o9 N- F+ cd <<<< 'c:\program $v'# c( R `: h! n {
PS (14) >
* T) D/ p- R! p4 z" r在扩展后,双引号被执行但单引号不能被执行,因为不在期望中的路径不存在所以行到了一个错误信息。看一下下面的例子:
4 c7 ~( \4 _ r; W `0 K! v+ G8 DPS (14) > '$v is $v'
' P6 F' n5 l7 N/ M" W" K8 H$ _$v is $v$ ~3 a0 [9 ?7 e
PS (15) > "$v is $v"6 f% F w: c* s J
files is files
?1 }0 m% E7 X4 d$ n在单引号的案例中,$v不加扩展,在双引号的案例中$v总是被扩展。但是我们想要看到什么$V的数值是什么呢?这是我们用的backtick的一个作用。它可以被用来引用或者逃避双引的字符串的美元标记来禁止扩展。让我们来试试:+ _5 m L/ E1 i( H0 f$ ]
PS (16) > write-output "`$v is $v"2 D5 Q1 M- a4 B% y' H) d6 U
$v is files' c o/ S. z# C7 h: I& L
现在假设我们想要显示$v的数值在另一行显示来代替引用。这是另一个形势我们可以使用backtick作escape字符.这个顺序 'n是字符串,既是单引用也是双引用,可以代替一个新行字符。我们可以写一个例子来体现分离行这种效果:
1 X$ a% V# M4 a' d0 D3 K) d1 ^1 e& _PS (19) > "The value of `$v is:`n$v", [5 P+ J4 e9 j/ b J+ W
The value of $v is:+ ~7 S" j/ v. {
Files
9 [9 a2 `2 {6 u8 M表2.1 列出了backtick特殊的字符
' K% H+ q6 x+ L) b! z4 c8 @, Q; D' V5 i8 ~/ [7 E7 H% M
注意,逃逸排序的处理时,像变量的扩展,只应用了双引号。在单引号里,输入什么会输出什么。在用脚本来完成子系统时提高引用处理的等级就相当的重要。
- I! h" w4 h5 m: [, B如果你用其它的像C,C#或者Perl之外的语言,你需要使用backslash来代替反斜杠。因为PowerShell在过去使用backslash来作一个路径分隔符,它不适合用backslash来作逃逸字符。太多的应用希望backslash来分隔路径,也许把每个路径用双斜线输入。选择一个不同的逃逸字符串时很难描述,但是没有选择。用户在使用PowerShell体验shell和脚本语言会受到巨大的思想碰撞,但最后,并不太困难,大多数用户接受了它。
附件: 您所在的用户组无法下载或查看附件
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP

2.2.3 表达式模式和命令模式的分析! g+ i' ]% q3 f! h- S; P4 T
早先谈及的,因为PowerShell是一种壳,它不得不处理其它语言中没有出现的语法分析的问题# I) \ p1 F* `$ K7 ]2 v& s( |
! P+ W- J' r- P2 A5 q
。实际上,大多数的语言都集合了小语言的许多不同的分析模式。PowerShell里,我们简化了
/ P% U" o$ _" z: r T9 `: P! W$ L5 M" b4 ~# O( V2 B7 Z
分析模式,并为它制定了下面的两种术语:表达式模式和命令模式。在表达式模式里,语法都
6 y' ?+ W$ g y* I
. z7 [9 V8 P, k% V2 j# q是传统的:字符串必须要引用,数字总是数字。。。。。。在命令行模式里,数值用数值处理
: F! N2 T3 @8 T M* ?" f- T3 s
6 Y& v" u! ^* n+ M$ y,但是除非参数用$,@, ', ", or (开始,其它的参数都作字符串处理.当一个参数从这些特殊字符
' q; V! H/ r4 U, l+ w
. v7 D9 L! W1 i8 G6 G& T之一开始,剩下的参数被分析成为数值表达式。(在字符串中也有特殊的语句来作变化时的参( o+ }5 m) H7 n0 ~
% \( C8 o6 C& S; E
考,我们将要在以后讨论)表2.2展示了一些例子详细的分析了每个模式中,项目是如何分析
( a5 p. W" R2 A k/ k% ?$ V( y i& [* h0 _
的。
. ]5 b* u/ |' ]& M% t表2.2 分析模式示例
2 u7 m# p% i! X# I命令行例子 分析模式和解释' c. S5 I% X* m6 B
2+2 表达式模式:结果是4 k% y* m' x% S7 J) m
write-output 2+2 命令模式:结果是"2+2": C# X# ?- m7 q2 h3 Q' y, M
$a=2+2 表达式模式:变量$a被分配成数值4
* C" d) c4 |2 M1 v4 ^( i% `0 B) Vwrite-output(2+2) 表达式模式:因为圆括号的关系,2+2被赋值成为一个产生4
, g! Y# A( B& i- E, j1 Z3 S) b" h
+ A$ T& I' ?7 w# g 的表达式。这个结果成了write-output cmdlet的自变量。. _* j b# c @ `7 [
write-output $a 表达式模式;产生了4,这的确是含糊的-------给它赋值另一
9 k$ n5 u0 y9 q: H1 I3 l& G/ _4 }5 y
# t9 I) K* `* n2 H: I8 j 模式会产生同一结果.下一个例子展示了为什么我们将它定义
7 j1 [) M* A+ ^- P
$ ?: v: l4 @9 B 为表达式模式而不是命令模式.2 o, g% E) K, u, G1 R" F
write-output $a.equals(4) 表达式模式;$a.equals(4)赋值为真,所以write-output把布 , z1 x* a, T. u/ ?

% q' _1 ^/ Z$ Y; A$ { 尔值写为真.这是为什么一个变量默认的被赋值为表达式。我
- I8 P; _( W( G8 O: p# e2 c9 @' v! u; R! ]; u( X; Z& j8 q9 p3 H
们在没有圆括号时也要让简单的方法和合适的表达式正常工 V1 L6 h* t+ M% C, v
6 v9 |( S0 \7 ?4 P8 ~% E$ k: j
作。
: p6 W# ]8 M0 d. f* S1 M) l5 K- G* y5 vwrite-output $a/foo.txt 命令模式;$a/foo.txt拓展成4/foo.txt。这相对于前面的例子 3 X1 C! T* c4 Z& x+ [$ [
; u0 Y5 C5 L# I
。我们想要在命令模式被赋值成字符串。表达式里,如果是 6 x, u" O% K3 p" H
" p0 b2 z7 h& b9 i! ^% e# v, E
非空表达式,解释器先分析表达式模式。作为备份方案,它 3 G* |: ~9 @% n. E E
; X. b7 w% O7 x3 X0 Y
会重新搜索命令模式的自变量。最后,它会像可扩展的字符
! T6 m) C, j3 d7 [9 n T
8 q4 v1 Q( I* x# Q 串一样被处理然后得到结果。; i: L: o/ g+ o b; F l1 y% f7 z
注意在write-output(2+2)案例中,开放的扩号引起在解释模式在第一个记号再一次建立时,解释7 B5 J. N5 z: m' Z
5 v. z$ Q Y9 E( _! }2 {; C; X
器会进入一个新的解释器等级。这意味着顺序2+2会被真的解释成表达式模式,而不是命令模
4 f- i a; ^) a, l) a
$ r0 }) G$ q% U0 |7 E6 n4 q式,所以表达式的结果(4)被发表了。同时,在上面的详表中,特别的提及了在字符串中的变6 N1 W6 Y6 X! I& r( Q

3 }3 T8 t) P' e6 P7 }* W# ?" l量指南预览。一个变量自己被处理成一个表达式,而不是一个变量后面跟随着任意的文本,这. u: |; F5 T, s4 [) L

- ~# E2 \' g- g% Y- z些文本全部都用双引号引用起来。你可以这样来写) U' Z, v& \. u4 }% j% G
cd $HOME/scripts
3 ^+ L! H: r0 o代替$ @& j* Z0 J6 l7 W8 }
cd "$HOME/scripts"
* i% g) r6 P O T/ A0 q! C在早先提及的过程中,引用和非引用的字符串被分析成不同的记号。这就是为什么1 G8 m. e3 ~1 N k' \% B
my-cmdlet -parm arg3 C8 Q+ J! _& [) K. C; S! f
把-parm处理成一个参数
`2 b: I- {8 amy-cmdlet "-parm" arg
8 H: B1 _ _8 I9 P& g5 l& B把-parm处理成一个自变量。
) a# @9 A) K( L' }9 ^" }在参数绑定中存在着很多附加的技巧。如果这类没有被引用的参数像-notAparameter不是my% n1 c' r5 \4 B7 M# s1 z+ J$ H
5 o9 x8 u& c t
-cmdlet的参数,它将被处理成自变量。也就是说write-host -this -is -a parameter不需要引用。
' i1 L# H7 h8 S s这里我们完成了对分析模式的基础,引用和命令的覆盖。无论如何,在命令可以取得任意的自
+ O) U% p, o* p# }2 h' W
1 D; B. U+ U" ^2 u, z, a变量清单之后,知道怎样结束语句就相当重要。我们将在下一段覆盖这点。
是日已过,命亦随减。如少水鱼,斯有何乐? 大众当勤精进,如救头燃。但念无常,慎勿放逸

                      

TOP