Powershell学习笔记——变量和命令

2018-06-09 09:57 更新

变量,伟大的变量

  Powershel支持变量,这个功能对用惯了CMD的开发人员来说,那简直就是惊喜——终于可以结束总是把环境变量搞乱的痛苦日子了。

  Powershell的变量是以$号作为前缀的,所有变量都必须以$号开头,比如$var1, $my_var_2……。按照惯例,变量名当然是字母数字和下划线的组合。不过Powershell的变量不完全符合惯例——它的变量几乎允许任意字符。不过,当你准备使用“$my var”这个“变量”的时候,你会得到一个错误,因为,对于包含特殊字符的变量名,需要点特别的标记——用一对大括号括起来——当然,如果你不嫌麻烦的话,你也可以用同样的手段来包装一下不含特殊字符的变量名。来看示例:

  1. PS F:\> $var1 = 1 
  2. PS F:\> ${my var} = 2 
  3. PS F:\> "$var1, ${my var}, ${var1}" 
  4. 1, 2, 1 
  5. PS F:\> 

  惊喜到这里还未结束。Powershell的变量都是有类型的,因为它们都对应于.NET中的基本数据类型,或者对象。做个实验:

  1. PS F:\> ${my var}.getType().fullName 
  2. System.Int32 
  3. PS F:\> $var2 = "James Fancy" 
  4. PS F:\> $var2.getType().fullName 
  5. System.String 
  6. PS F:\> 

  可以看到,刚才定义的${my var}是Int32类型,而新定义的$var2是String类型,而它们的类型,完全是由它们的值决定的,这个,仔细观察一下定义这两个变量的那两条命令就明白了。于是,这里引发一个问题,既然变量是有类型的,那是否可以指定类型呢?答案是肯定的:

  1. PS F:\> [long] $var3 = 1 
  2. PS F:\> $var3.getType().fullName 
  3. System.Int64 
  4. PS F:\> [string] $var3 = $var3 
  5. PS F:\> $var3.getType().fullName 
  6. System.String 
  7. PS F:\> 

  这个例子很好的解释了,可以通过前缀由方括符包含的类型名称来为变量指定类型,而且还带出两点惊喜:第一,变量的类型是可以改变的;第二,从长整型到字符串类型可以直接转换而不需要特别的工具或者函数,当然,这还可以扩展到其它类型的转换。

  现在我们需要了解一下,常见的类型都有哪些呢?简单的列举一下:bool、char、byte、sbyte、int16、int32或int、int64或long、uint16、uint32、uint64、float或single、double、string、datetime、guid、xml、switch……除此之外,还有另外一些内置的类型,以及.NET库中的所有类和结构——太给力了!

  这些内置数据类型之间大多可以自动转换。在表达式中,如果存在混合类型的运算,多数时候是以先出现的那个变量的类型为准来进行运算,比如

  1. PS F:\> 2 + "2" # 先出现整型,后面的字符串转换为整进行整数运算 
  2. PS F:\> "2" + 2 # 先出现字符串型,后面的整形转换成字符符进行连接运算 
  3. 22 
  4. PS F:\> 

常量和只读变量

  变量是有了,Powershell能定义常量么?当然可以,不过需要用new-variable来定义:

  1. PS F:\> new-variable myConst "James Fancy" -option constant 
  2. PS F:\> $myConst 
  3. James Fancy 
  4. PS F:\> 

  常量是不能改变的,尝试给它重新赋值会抛出错误。这不是悲剧,悲剧的是,常量不能被删除,就算加上-force参数也不能被删除。

  1. PS F:\> del -force variable:myConst 
  2. Remove-Item : 无法删除变量 myConst,因为该变量为常量或者为只读变量。如果该变量 
  3. 为只读变量,请指定 Force 选项,然后重试此操作。 
  4. 所在位置 行:1 字符: 4 
  5. + del <<<<  -force variable:myConst 
  6.     + CategoryInfo          : WriteError: (myConst:String) [Remove-Item], Sess 
  7.    ionStateUnauthorizedAccessException 
  8.     + FullyQualifiedErrorId : VariableNotRemovable,Microsoft.PowerShell.Comman 
  9.    ds.RemoveItemCommand 
  10.  
  11. PS F:\> 

  不过这个常量并不是永驻于你的操作系统了,只需退出当前控制台,再开启一个新的控制台,你就会发现,一些都是崭新的,没有之前定义的一切东西:函数、变量以及删不掉的常量。

  话说回来,如果需要一个可以删除的常量,那不妨考虑下只读变量,只读变量有两种方式产生,一种是跟定义常量一样,在通过new-variable命令定义的时候指定-option为readonly;另一种是在变量已经存在的情况下,改变其选项。

  1. PS F:\> new-variable rVar "James" -option readonly # 第一种方法 
  2. PS F:\> $rVar2 = "Fancy" # 第二种方法,先定义一个普通变量 
  3. PS F:\> (get-variable rVar2).options = "readonly" # 再通过get-varialbe取得变量对象并改变选项 
  4. PS F:\> # 当然上面这句话也可以用set-varialbe命令来完成,就像这样 
  5. PS F:\> # set-variable rVar2 -option readonly 
  6. PS F:\> 

  只读变量是可以被删除的,当然需要-force参数。只读变量也可以变回普通变量,只需要改变其选项,当然也需要-force参数。

  1. PS F:\> del variable:rVar -force # 删除只读变量rVar 
  2. PS F:\> set-variable rVar2 -option none -force # 将rVar2变成普通变量 
  3. PS F:\> 

Device, Powershell的命名空间

  上面提到变量的时候已经多次使用了“variable:变量名”这种形式的东东。这里的“varialbe:”被称作Device,就好像C:、D:、E:、F:一样。也许理解起来有点困难,不过,把它想像成“命名空间”应该就好理解了。

  上面的示例中定义了$var1、$var2、${my var}等变量,其它它们的全称应该是$variable:var1、$variable:var2、${varialbe:my var}。除了variable之外,常用的命名空间还有env、function、alias等。

Powershell的命令

  如果想知道Powershell有哪些命令可以用,help已经说明了,可以用get-command来查看。在控制台输入help get-command之后,就可以看到get-command的用法。

  在get-command的语法中可以看到一个-CommandType参数,它允许get-command按类型查询命令,其中类型包括Alias、Function、Filter、Cmdlet、ExternalScript、Application和Script。最后一项scrip我没搞懂,不过前面几项分别是:
Alias,别名,通过set-alias命令为Cmdlet、Function等命令设置的一个简单易记的名称。
Function,函数,你懂的。
Filter,一种特别的函数,用于在重定向操作中过滤对象列表。
Cmdlet,可以理解为Powershell的内置命令——当然,Powershell的内置命令是可以扩展的。
ExternalScript,所有在路径(由$env:path变量的值说明)中的.ps1脚本
Application,毫无悬念,路径中的.exe文件(其实应该说是PE文件,因为.dll等也算在内)

Cmdlet

  Cmdlet是Powershell的内置命令,比如之前用到的get-command就是一个Cmdlet。按Powershell的规范,Cmdlet的名字都是由动词和宾语构成的,以说明这个Cmdlet的作用,其结构是“动词-宾语”。比如get-command的意思就很明显,是获取命令相关的信息的。

  同样,通过help get-command,可以在其说明文档中找到get-command的第二种语法里有一个-verb参数,提供通过动词来查找命令的功能。这里的动词包括get、set、test……很多,而且可以自己定义。比如“get-command -verb go”找不到有匹配的命令,但是如果定义了一个名叫"go-url"的函数之后,再运行“get-command -verb go”就可以将刚定义的“go-url”显示出来了,就像这样:

  1. PS F:\> get-command -verb go 
  2. PS F:\> function go-url() { "going..." } 
  3. PS F:\> get-command -verb go 
  4.  
  5. CommandType Name Definition 
  6. ----------- ---- ---------- 
  7. Function go-url param()... 
  8.  
  9.  
  10. PS F:\> 

  上面提到Cmdlet是可以扩展的,的确如此。你可以自己按照规范来写DLL扩展Cmdlet,当然那不是一件简单的事情。对于脚本的常规用法来说,它太复杂了,所以我在短期内没准备去学习它。

Alias,别名

  我们曾经多次使用help命令,其实它是一个别名——或者说得拟人一点,叫昵称。help是get-help的另一个名字,输入get-help很麻烦,因为它包含8个字符,其中一个还是符号,所以懒人们发明了“别名”,为它取了另一个更简明的名字,help。

  当然,并不是只有get-help享受了这个待遇。如果你在控制台中键入alias命令,就可以看到目前已经定义了的所有别名,以及它们对应的原始命令。当然,这里显示的只是已经定义的,如果你愿意,随时可以添加新的别名。比如刚才的示例中定义了一个go-url函数,那么现在为它取个新名字,叫url:

  1. PS F:\> set-alias url go-url 
  2. PS F:\> url 
  3. going... 
  4. PS F:\> 

  甚至,还可以为别名指定别名,比如

  1. PS F:\> set-alias myurl url 
  2. PS F:\> get-alias url,myurl 
  3.  
  4. CommandType Name Definition 
  5. ----------- ---- ---------- 
  6. Alias url go-url 
  7. Alias myurl url 
  8.  
  9.  
  10. PS F:\> 

  这里,get-alias会显示指定的别名列表中每个别名的信息。
如果不想要某个别名了,可以用del命令删除它——哦,del也是个别名,真实的命令是remove-item。

  1. PS F:\> del alias:url 
  2. PS F:\> 
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号