PS C:/> get-command -CommandType cmdlet CommandType Name Definition ----------- ---- ---------- Cmdlet Add-Content Add-Content [-Path] <String[]> [-Value] <Object[... Cmdlet Add-History Add-History [[-InputObject] <PSObject[]>] [-Pass... Cmdlet Add-Member Add-Member [-MemberType] <PSMemberTypes> [-Name]... Cmdlet Add-PSSnapin Add-PSSnapin [-Name] <String[]> [-PassThru] [-Ve... Cmdlet Clear-Content Clear-Content [-Path] <String[]> [-Filter <Strin... Cmdlet Clear-Item Clear-Item [-Path] <String[]> [-Force] [-Filter ... Cmdlet Clear-ItemProperty Clear-ItemProperty [-Path] <String[]> [-Name] <S... |
这里我省略了绝大部分的显示(^^), PowerShell Version 1.0 微软官方发布的版本包含了
PS C:/> (get-command -CommandType cmdlet).count 129 |
129确实有点多, 但是实际上在学习过程中你会发现学习他们的过程比你学习unix shell中命令更加容易些, 原因稍后为你解答.
cmdlet是可以进行扩展的, 如果你想开发自己的cmdlet, 你需要下载PowerShell SDK. 目前, 我只知道该 SDK 包含在了Windows Vista Platform SDK中. 下载该 SDK, 需要进行正版验证. 在伴随着教程的编写过程, 我也会阅读PowerShell SDK中关于PowerShell的介绍, 并尽量用最简单的语言将需要注意的内容, 传达给大家.
cmdlet的开发并不复杂, 可以使用C#作为实现语言, PowerShell SDK已经实现了好了cmdlet的一个基类, 开发的cmdlet只需要继承该基类. 通过这种开发模式, 最大的优点:
(1). 所有的cmdlet中包含了一些公共参数(common parameters), 例如: -Verbose, -Debug, -ErrorAction, -ErrorVariable, and -OutVariable. 这些参数大多用于一些脚本调试等.
(2). 所有的cmdlet中的参数(parameters)具有相似的参数, 相同的类型, 甚至具有相同的性质. 对于接受输入的某些cmdlet来说, 输入的参数就叫做-InputObject, 参数类型一般是[object[]], 而通常都会具有从管道线读取处理对象的属性.
这种一致性带来的最大好处就是, 对于一个命令, 往往你只需要关注命令的特性, 不需要记住复杂繁多的参数. 如果你熟悉unix shell下的utils core tools那么我相信, 例如awk使用-F指定一个支持正则表达式的与分隔符, cut使用-d来分割, sort使用-t进行分割对你来说是痛苦的. 在PowerShell中, 你甚至不需要对cmdlet产生的输出进行分割. 这点你会在稍后看到.
cmdlet编译后的结果不是可执行文件, 而是dll文件, PowerShell启动时, 将这些命令加载, 这些命令执行效率最高, 因为他们在PowerShell时被载入PowerShell进程内.
2. 函数(function)
函数, 准确的说就是: 有名称的代码块(scriptblock). 下面就是一个简单的函数定义:
PS C:/> function Get-DayToBeiJingOlympic >> { >> ([datetime] "2008-08-08" - [datetime]::Now).Days; >> } >> PS C:/> Get-DayToBeiJingOlympic 370 |
细节大家可以不用关心, 稍后都会讲到. 函数就是一段你输入到PowerShell的命令集合.
但是函数在被定义后, 才存在于PowerShell内存中, 当PowerShell退出时, 就会消失.
效率上, 函数在第一次调用时需要编译, 因此第一次调用速度较慢.
3. 脚本(script)
PowerShell在交互式Shell(interactive Shell)和脚本语言(script Language)之间进行了平衡, 提供了执行脚本的能力. 脚本类似于函数, 存放在文件中, 调用时由PowerShell载入内存, 编译并执行.
效率上来讲, 脚本慢于函数(function), 主要原因在于函数只会在第一次调用时被编译, 而脚本每次调用都会被编译一次. 但是编译后的执行阶段, 他们的性能是近似相等的.
4. native Windows command
我不知道应该这个东西用什么名字. 这类命令在Windows世界大量存在, 譬如: dir, findstr, del, ping. 这些命令就是Windows之前的可执行文件(非.Net命令行可执行文件). 在PowerShell中调用这些命令效率是最低的, 因为执行他们PowerShell需要创建一个新进程. 此外因为这些命令早于PowerShell, 因此他们的信息输出都是基于文本的(也可以说是字符串), 因此丧失了PowerShell对对象的处理能力. 因此, 如果你知道PowerShell的实现, 就避免使用这些命令.
讨论完命令, 我简单介绍下别名(alias):
PS C:/> (Get-Command -CommandType alias).count 101 |
你一定在想, PowerShell为什么提供了这么多别名, 难道要累死我们??
PowerShell为了方便使用windows和unix, linux的人们, 支持了两套别名, 譬如dir相对于ls, 还有unix, linux的grep等. 这样无论你使用windows还是linux都能相对来说快速的上手PowerShell.
PowerShell Version 1.0中有一个缺陷, 既定义别名时, 不允许指定参数. 这无疑是PowerShell的一个缺陷. 但是因为cmdlet中参数较少(一般都是10个以内), 因此大多数时候, 你不需要定义带有参数的别名, 如果真的需要, 可以用函数来替代. 这种缺陷, 与代码块的执行等功能有冲突. 希望在后续版本能有别名功能能够更加强大.
写在最后:
如果您有幸坚持看了我的啰唆, 我非常的感激. 接下来的3, 4讲也会偏向于概念而非更多的语法. 任何事, 请相信你对解释器行为的理解, 对语言的特性的理解, 都会让你在编写该语言代码时受益匪浅. 因此, 请坚持, 努力的去学习. 我希望在这份漫长教程过程中, 带给大家更多计算机历史, 发展; 不同语言, 技术的对比; 编写健壮代码(无论是像C, C#还是像sh, PowerShell)的思路. 在03, 04中, 我会介绍两个关键核心的概念(算法??), 参数绑定和类型转换.
学习一门语言, 还能学到编程的心得, 这也是我希望的. 最后, 谢谢关注教程的人, 因为本人工作方向问题, 教程编写速度可能较慢, 还望大家多多见谅.