美文网首页野生技术宅协会程序员
Powershell快速入门(二) Shell编程

Powershell快速入门(二) Shell编程

作者: 乐百川 | 来源:发表于2017-05-20 02:56 被阅读349次

    这一部分着重于介绍Powershell的程序知识,让我们能够编写功能强大的Powershell脚本,执行比较复杂的任务。

    变量

    变量使用$变量名创建和引用。举个例子,Get-Location命令用于获取当前工作目录位置,它的别名是pwd。那么我们可以使用下面的命令来创建一个变量,存储当前目录位置。

    C:\Users\asddf> $current=pwd
    

    然后我们访问$current,就可以获取实际值了。

    C:\Users\asddf> $current
    
    Path          
    ----          
    C:\Users\asddf
    

    如果知道这个命令返回的实际是.NET对象的话,我们还可以更进一步,比方说直接访问这个对象的Path属性,获取值。

    C:\Users\asddf> $current.Path
    C:\Users\asddf
    

    还有一个命令Get-Member,别名是gm,用于获取对象的属性。比方说,我们将Get-Location命令的结果通过管道传递给Get-Member命令,就会显示下面的输出。如果不了解.NET的话,可能感觉比较陌生。但是如果你懂得.NET和C#的话,就会像我一样大喊一声:“卧槽,还能这样玩?!”

    C:\Users\asddf> Get-Location|Get-Member
    
    
       TypeName:System.Management.Automation.PathInfo
    
    Name         MemberType Definition                                               
    ----         ---------- ----------                                               
    Equals       Method     bool Equals(System.Object obj)                           
    GetHashCode  Method     int GetHashCode()                                        
    GetType      Method     type GetType()                                           
    ToString     Method     string ToString()                                        
    Drive        Property   System.Management.Automation.PSDriveInfo Drive {get;}    
    Path         Property   string Path {get;}                                       
    Provider     Property   System.Management.Automation.ProviderInfo Provider {get;}
    ProviderPath Property   string ProviderPath {get;}
    

    如果我们要获取对象的所有属性,使用MemberType参数。

    C:\Users\asddf> pwd|gm -MemberType Property
    

    我们还可以在变量上调用方法, 比如说将路径转换为全小写。

    
    C:\Users\asddf> $current.Path.ToLower()
    c:\users\asddf
    

    最后,如果不再需要一个变量,可以使用Remove-Variable删除变量,它的别名是rv

    C:\Users\asddf> Remove-Variable current
    

    操作符

    来看看Powershell中支持的操作符。

    数学运算符

    首先,基本的数学运算符都是支持的。

    PS D:\Desktop> $i=5
    PS D:\Desktop> $sum=3+4*($i-3)/2
    PS D:\Desktop> $sum
    7
    

    前置后置自增自减运算符也是支持的。

    PS D:\Desktop> $i=0
    PS D:\Desktop> $i--
    PS D:\Desktop> $i++
    PS D:\Desktop> ++$i
    PS D:\Desktop> --$i
    

    比较运算符

    然后是比较运算符,这些和Linux Shell中很相似,有大于(-gt),大于等于(-ge),小于(-lt),小于等于(-le),等于(-eq),不等于(-ne)几个。

    字符串匹配运算符

    -like-notlike用于?*这样的通配符。

    PS D:\Desktop> 'hello' -like '?ello'
    True
    PS D:\Desktop> 'hello' -notlike '?ello'
    False
    PS D:\Desktop> 'hello' -like '*o'
    True
    

    -match-notmatch用于正则表达式。

    PS D:\Desktop> 'aabcc' -match 'a*b?c+'
    True
    PS D:\Desktop> 'aab' -match 'a*b?c+'
    False
    

    包含和替换运算符

    -contains查找序列中是否包含某个元素。

    PS D:\Desktop> 'hello','zhang3' -contains 'zhang3'
    True
    

    -replace用于替换字符串中某个部分,当然正则表达式也是支持的。

    PS D:\Desktop> 'hello zhang3' -replace 'zhang3','yitian'
    hello yitian
    

    分隔和连接运算符

    -split-join用于将一个字符串分为几个子部分,或者将几个子部分组合为一个字符串。

    PS D:\Desktop> 'A B C DE' -split ' '
    A
    B
    C
    DE
    PS D:\Desktop> 'A','B','C' -join ','
    A,B,C
    

    上面这些运算符都是大小写不敏感的,如果需要大小写敏感的功能,可以在运算符前面添加c前缀。

    PS D:\Desktop> 'yitian' -match 'Yitian'
    True
    PS D:\Desktop> 'yitian' -cmatch 'Yitian'
    False
    

    逻辑运算符

    逻辑运算符有与(-and)、或(-or)、非(-not!)以及异或(xor)几个,并且支持短路计算。

    如果需要使用真值和假值字面量,可以使用$true$false

    类型运算符

    Powershell 和.NET平台绑定,所以它是一门强类型的脚本。因此我们可以在脚本中判断数据的类型,只要使用-is-isnot运算符即可,类型需要写到方括号中。这里的类型可以是所有合适的.NET类型。

    PS D:\Desktop> 3.14 -is [Double]
    True
    PS D:\Desktop> 3.14 -isnot [Float]
    True
    

    重定向运算符

    这个稍微比较麻烦一点。

    首先是>>>运算符,用于将标准输出流重定向到文件,前者会覆盖已有文件,后者则是追加到已有文件末尾。

    然后我们来说说日志级别,如果有使用过某些语言的日志框架的话,就很好理解了。在这里,2代表错误、3代表警告、4代表信息、5代表调试信息。n>n>>运算符就是用于将对应级别的输出重定向到文件的,这两者的区别和前面相同。n>&1将对应级别的输出和标准输出一起重定向到文件。

    最后就是*>*>>了,这两者将所有输出信息重定向到文件。

    需要注意,Powershell使用Unicode编码来输出信息。如果你需要使用其他类型的编码,就不能使用重定向运算符了,而应该使用Out-File命令。

    特殊运算符

    &运算符将它后面的命令设置为后台运行,当运行的命令需要阻塞当前终端的时候很有用。

    .\\运算符用于执行一个脚本或命令。如果执行的是Powershell脚本,那么脚本会在自己的作用域中执行,也就是说在当前环境下无法访问被执行的脚本中的变量。

    []运算符用于转换变量的类型,比如说下面的代码,就将pi变量转换为了Float类型。

    [Float]$pi = 3.14
    $pi -is [Float]
    

    .运算符用于调用.NET对象的成员,它也可以用于执行脚本。当它用于执行脚本的时候,脚本会在当前作用域中执行。所以脚本结束之后,我们可以访问脚本中的元素。

    ::运算符用于调用类中的静态成员,例如下面就会调用.NET平台中DateTime类的Now属性。

    PS D:\Desktop> [DateTime]::Now
    
    2017年5月18日 22:45:42
    

    ..运算符用于创建一个范围闭区间,例如下面这样。

    PS D:\Desktop> 1..3
    1
    2
    3
    PS D:\Desktop> 3..1
    3
    2
    1
    

    -f运算符用于格式化数据,例如下面这样。格式化方法和C#中的完全相同,所以如果不熟悉的话直接看在C#中如何格式化数据就行了。

    PS D:\Desktop> 'My name is {0}, I am {1} years old' -f 'yitian',24
    My name is yitian, I am 24 years old
    

    $运算符可以将字符串内部的变量转换为实际的值,例如下面这样。需要注意使用内插操作符的时候,外部字符串需要使用双引号,否则Powershell会直接输出字符串内容。

    PS D:\Desktop> $name='yitian'
    PS D:\Desktop> $age=24
    PS D:\Desktop> "My name is $name, I am $age years old."
    My name is yitian, I am 24 years old.
    

    @()运算符用于将一系列值转换为一个数组。假如在脚本中有一个函数可能返回0、1或多个值,就可以使用这个操作符,将一系列值合并为一个数组,方便后续处理。

    ,逗号运算符如果放置在单个值前面,就会创建一个包含这个值的单元素数组。

    条件判断

    if判断

    Powershell中的条件判断和一般的编程语言以及Shell编程都很类似,直接看代码就能理解。

    $condition = $true
    
    if ($condition -eq $true) {
        Write-Output "condition is $true"
    }
    elseif ($condition -ne $true ) {
        Write-Output "condition is $false"
    }
    else {
        Write-Output "other ocndition"
    }
    

    switch判断

    如果需要多重判断,可以考虑使用switch语句。一个典型的switch如下所示。

    $n = 4
    switch ($n) {
        1 {"n is 1"}
        2 {"n is 2"}
        3 {"n is 3"}
        default {"n is others"}
    }
    

    其实细说起来,这个switch的坑还是不少的。例如,switch语句可以接受多个值来测试,在switch语句中还可以编写多个case相同的语句。这里我就不细说了,想具体了解的话直接看官方文档 about_Switch吧。

    循环语句

    提醒一下,不管是哪种循环语句,在循环体内都可以使用breakcontinue中断/继续循环。

    do循环

    首先来看看do-while循环,先执行循环体,然后判断是否满足条件,如果满足条件则继续执行。

    $i = 0
    do {
        $i++
        Write-Output $i
    }while ($i -ne 3)
    

    然后是do-until循环,和do-while类似,不过当条件不满足的时候才会继续循环,如果满足条件则退出循环。

    $i = 0
    do {
        $i++
        Write-Output $i
    }until ($i -eq 3)
    

    while循环

    while循环是先判断循环条件,满足条件时执行循环。

    $i = 0
    while ($i -lt 3) {
        Write-Output $i
        $i++
    }
    

    for循环

    for循环可以看做是while循环的另一种形式,常用于固定次数的循环。

    for ($i = 0; $i -ne 3; $i++) {
        Write-Output $i
    }
    

    for-each循环

    for-each循环用于遍历一个集合中的所有元素。

    $array = @(1, 2, 3, 4)
    foreach ($i in $array) {
        Write-Output $i
    }
    

    值得一提的是,for-each语句用在管道上时,还有以下一种用法。

    <command> | foreach {<beginning command_block>}{<middle command_block>}{<ending command_block>}
    

    使用这种方法时,for-each后面可以跟三个语句块,第一个语句块是开始语句块,在循环前执行一次,常用来初始化一些数据;第三个是结束语句块,在循环结束之后执行一次,常用于统计一些循环数据;第二个就是正常的循环语句块,会循环多次。

    函数

    定义函数

    定义函数使用function关键字。

    function hello {
        Write-Output 'Hello Powershell'
    }
    

    定义好函数之后,就可以使用函数名来调用函数了。

    hello
    

    函数的参数

    函数当然也可以带参数了,参数列表有两种写法:第一种是C风格的,参数列表写在函数名后面,使用小括号分隔开;第二种方式是在方法体中,使用param关键字声明参数。这两种方法是完全等价的,当然我习惯上还是喜欢使用第一种方式。

    Powershell是一种强类型的脚本语言,所以可以在参数列表上添加参数类型,参数类型是可选的,不过我还是推荐写的时候带上类型,方便阅读和类型检查。

    function Say-Hello ([string] $name) {
        Write-Output "Hello, $name"
    }
    
    function Say-Hello2 {
        param([string] $name)
        Write-Output "Hello, $name"
    }
    

    调用带参数的函数时,需要向调用命令那样,使用-参数名来传递参数,例如下面这样。

    Say-Hello -name 'yitian'
    

    默认参数

    Powershell支持默认参数,直接用赋值号=在参数列表上指定参数默认值即可。

    
    function Say-Hello3 {
        param([string] $name = 'zhang3')
        Write-Output "Hello, $name"
    }
    

    位置参数

    Powershell也支持位置参数,它会把所有参数包装到$args数组中,所以我们可以通过这个变量访问所有位置的参数。例如下面,将所有参数合并一个字符串,然后打印出来。

    function Say-Hellos {
        $names = $args -join ','
        Write-Output "Hello, $names"
    }
    

    这个函数调用时候需要指定多个参数,注意不要在多个参数之间添加括号,否则会变成一个数组参数,而不是多个参数。

    Say-Hellos 'yitian' 'zhang3' 'li4'
    

    开关参数

    开关参数没有类型,作用仅仅是标志是或者否。如果在使用函数的时候带上开关参数,那么它就是的状态,否则就是的状态。开关参数需要指定参数类型为switch

    function Answer-Hello ([switch] $yes) {
        if ($yes) {
            Write-Output "Hi"
        }
    }
    

    然后在调用时就可以看出区别了。

    Answer-Hello -yes
    Answer-Hello 
    

    函数返回值

    最后来说说函数返回值。这个其实也很简单,只要使用return语句就可以了。

    function Add ([double]$a, [double]$b) {
        $c = $a + $b
        return $c
    }
    

    然后我们调用函数,就可以看到结果了。

    Add -a 3 -b 5
    

    关于Powershell编程的知识就介绍到这里,其实如果看看官方文档的话,就知道这里介绍的也仅仅是一部分而已。不过这一部分对于我们日常使用和学习基本上也够用了。

    如果要查看详细帮助的话,可以运行一下下面的命令,这样会显示所有和Powershell相关的帮助文档。

    Get-Help about*
    

    然后,就可以阅读自己感兴趣的部分了。比方说,如果我们想了解用Powershell编写类,就可以使用下面的命令。如果想在浏览器中浏览器在线版本,加上-online参数即可。

    Get-Help about_Classes
    

    参考资料

    https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_operators?f=255&MSPPError=-2147217396

    http://windowsitpro.com/powershell/windows-powershell-operators

    相关文章

      网友评论

        本文标题:Powershell快速入门(二) Shell编程

        本文链接:https://www.haomeiwen.com/subject/zljexxtx.html