zoukankan      html  css  js  c++  java
  • Powershell 变量

        本文主要和大家描述一下关于Powershell变量的详细内容,上回和大家聊到了Powershell的远程管理,有朋友反映Powershell的基础只是还不够了解,所以先谈谈在Powershell中的变量问题.

    创建自己的变量

    PS C:\Users\Terry> $a = 1.2  那么我们就创建了一个名字为a的变量,注意Powershell 中变量都用美元符号"$"做为开始.

    PS C:\Users\Terry> $b = 2.3 我们再次创建了一个为b的变量,两个变量是可以直接进行运算的,例如对他们进行一个乘操作.

    PS C:\Users\Terry> $a*$b
    2.76

    很明显的,我们也可以对变量直接进行变量区间的传递赋值:

    PS C:\Users\Terry> $c=$a*$b
    PS C:\Users\Terry> $c
    2.76

    当使用字符串变量的时候,这里有一些小的技巧,大家可以注意了:

    PS C:\Users\Terry> "`$c=`$a*`$b equals $c"
    $c=$a*$b equals 2.76

    在字符串""包围的区间要引用变量,可以很简单的,直接"$变量" 来表达我们的变量值,当我们需要转移$或者双引号等特殊字符使用我们通常使用"`"(1旁边那个键).

    接下来可以进行更复杂的运算,如果在字符串引用变量进行进一步运算:

    比如我们想在字符串中直接显示变量a和变量b的乘积值

    PS C:\Users\Terry> "$a*$b"
    1.2*2.3

    这样是不行的.

    通常我们使用

    PS C:\Users\Terry> "$($a*$b)"
    2.76

    来进行一个转换,同理的.

    我创建一个数组,然后求他的数组长度

    PS C:\Users\Terry> $arr=1,2,3,4
    PS C:\Users\Terry> $arr
    1
    2
    3
    4
    PS C:\Users\Terry> "`$arr array length equals $arr.Length (this is error)"
    $arr array length equals 1 2 3 4.Length (this is error)
    PS C:\Users\Terry> "`$arr array length equals $($arr.Length) (this is ok)"
    $arr array length equals 4 (this is ok)

    如果我们的变量名比较复杂,存在空格,或者特殊字符,一般我们直接使用是会出错的,Powershell默认会使用空格或者一些特殊字符作为分解符号(DELIMITER)

    比如:

    PS C:\Users\Terry> $a b=123
    表达式或语句中出现意外标记“b=123”。
    所在位置 行:1 字符: 9
    + $a b=123 <<<<
        + CategoryInfo          : ParserError: (b=123:String) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : UnexpectedToken

    这样创建一个$a b 的变量就有问题了.所以要使用{}来对变量名进行一个解析:

    PS C:\Users\Terry> ${a b}=123
    PS C:\Users\Terry> ${a b}
    123
    PS C:\Users\Terry> "${a b}"
    123

    变量返回值

    当我们调用一些命令的时候,我们还可以把返回值直接赋予给变量.

    比如:

    PS C:\Users\Terry> $ret = ls
    PS C:\Users\Terry> $ret


        目录: C:\Users\Terry


    Mode                LastWriteTime     Length Name
    ----                -------------     ------ ----
    d----        2010/11/15     10:43            CMB
    d-r--         2010/11/4     19:18            Desktop
    d----        2010/11/18     15:23            Tracing
    -a---        2010/11/16     16:24      11544 a
    -a---        2010/11/13     14:30      21466 function.ps1


    PS C:\Users\Terry> $ret.GetType()

    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array

    我将枚举目录的结果直接返回给变量$ret,查看$ret的类型是Object[] 数组.

    Powershell变量魅力

    一键赋值能力:

    PS C:\Users\Terry> $a=$b=$c=1
    PS C:\Users\Terry> $a
    1
    PS C:\Users\Terry> $b
    1
    PS C:\Users\Terry> $c
    1

    变量交换能力:

    PS C:\Users\Terry> $a=1;$b=2
    PS C:\Users\Terry> $a,$b=$b,$a
    PS C:\Users\Terry> "$a $b"
    2 1

    使用Powershell还可以非常方便的访问文件

    比如我们在c:\根目录下创建一个1.txt 里面随便写入内容

    我们可以直接使用

    PS C:\Users\Terry> ${c:\1.txt}
    123123123

    PS C:\Users\Terry> $command = "`${$env:windir\windowsupdate.log}"
    PS C:\Users\Terry> Invoke-Expression $command

    来查看内部的内容,某些时候,我们可以用来查询windows日志:

    这里有一个小技巧,我们直接使用环境变量$env:windir再在外部使用$来打开文件时候是不能正确解析的,他会被当作变量名的文件路径了

    所以我们要把调用的命令解析成可执行的方式交给Invoke_Expression 来使用 .

    维护Powershell变量

    首先是查找变量

    可以使用DIR/Get-ChildItem (是Alias对)

    PS C:\Users\Terry> dir variable:

    Name                           Value
    ----                           -----
    $                              $a $b
    ?                              True
    ^                              $a $b
    _
    a                              2
    a b                            123
    args                           {}
    arr                            {1, 2, 3, 4}
    b                              1
    c                              1

    我们刚才创建的变量就可以看到了.

    当然具体的帮助大家可以看看Get-Help Get-ChildItem –Full 看看如果进行-include和-exclude操作.当我们要查找我们的a变量的时候,通常会这样搜索:

    存在字符串1的数组行:

    PS C:\Users\Terry> dir variable:|Out-String -Stream|Select-String "1"

    $                              1
    a b                            123
    arr                            {1, 2, 3, 4}
    b                              1
    c                              1
    PID                            1396
    PROFILE                        E:\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
    PSHOME                         C:\Windows\System32\WindowsPowerShell\v1.0
    ReportErrorShowSource          1
    text                           $a*$b={123*0.19}

    当我们要验证某个变量是否存在的时候,可以使用Test-Path

    PS C:\Users\Terry> Test-Path variable:\a
    True

    说明变量a是存在.

    删除变量:

    PS C:\Users\Terry> Remove-Variable -Name a
    PS C:\Users\Terry> del variable:\b
    PS C:\Users\Terry> $a
    PS C:\Users\Terry> $b

    使用Remove-Variable 或者是Del 来删除变量.

    关于变量操作的 Ps cmd 大家可以直接使用来搜:

    PS C:\Users\Terry> Get-Command -Noun Variable

    CommandType     Name
    -----------     ----
    Cmdlet          Clear-Variable
    Cmdlet          Get-Variable
    Cmdlet          New-Variable
    Cmdlet          Remove-Variable
    Cmdlet          Set-Variable

    在Powershell中还存在许多的windows环境变量,$env:*之类的

    大家可以看看dir env:来看看系统变量.

    最后 Powershell变量的作用域

    Powershell 会存在一个作用域,也就是变量在那个作用域下可用.我们需要了解的有4个作用域:

    global,private,local,script

    我们先看看官方是怎么表述的:

    Scope allocation
    Description

    $private:test = 1

    变量只能在当前作用域,脚本,函数可见,不能传递给其他的作用域,同理也只能在当前作用域下读写.
    $local:test = 1

    变量在本地作用域下创建,这是创建变量的默认作用域,本地作用域变量能够在其他作用域下读取,但是不能通过其他作用域修改,只有本地作用域能够修改.
    $script:test = 1

    脚本作用域变量只在脚本中有效,他可以在脚本的任何作用域下可见.比如在一个脚本的函数下创建了一个变量,那么在脚本的外部的函数也是可以访问的到的.
    $global:test = 1

    变量任何作用域下可用,甚至是外部函数和脚本.
    我们来做几个测试加强对这个概念的理解:

    PS C:\Users\Terry> notepad test.ps1

    我们先打开一个测试的脚本test.ps1在里面输入:

    $windows = $env:windir
    "Windows Folder: $windows"

    保存关闭以后,执行

    PS C:\Users\Terry> Set-ExecutionPolicy RemoteSigned

    执行策略更改
    执行策略可以防止您执行不信任的脚本。更改执行策略可能会使您面临 about_Execution_Policies
    帮助主题中所述的安全风险。是否要更改执行策略?
    [Y] 是(Y)  [N] 否(N)  [S] 挂起(S)  [?] 帮助 (默认值为“Y”): y

    我们的Powershell默认是不允许执行没有签名的脚本,所以我们设置成RemoteSigned.允许本地未签名脚本.

    PS C:\Users\Terry> $windows = "Hello"

    PS C:\Users\Terry> & .\test.ps1
    Windows Folder: C:\Windows
    PS C:\Users\Terry> $windows
    Hello

    (小技巧,执行脚本的时候,要使用&或者. 路径的方式)

    我们首先在当前作用域下创建 windows 变量,然后调用脚本,脚本复制为 c:\windows,执行完脚本以后,windows变量还是Hello

    再来回顾一下我们当时的定义:

    变量在本地作用域下创建,这是创建变量的默认作用域,本地作用域变量能够在其他作用域下读取,但是不能通过其他作用域修改,只有本地作用域能够修改.

    我们修改test.ps1在顶部加上:$windows 增加一个打印,再次执行:

    PS C:\Users\Terry> $windows = "Hello"

    PS C:\Users\Terry> & .\test.ps1
    Hello

    Windows Folder: C:\Windows
    PS C:\Users\Terry> $windows
    Hello

    也证实了,官方的定义.只能读取不能修改.

    关于Global 没有太多想解释的..$global:test=1创建就好了(这里强调一个,所有变量都 只对当前Session有效,也就是一个Powershell进程)

    那么我们来看看private变量

    PS C:\Users\Terry> $private:a=1
    PS C:\Users\Terry> $a
    1
    PS C:\Users\Terry> function test{$a}

    PS C:\Users\Terry> test

    没有任何输出,说明private 是不能跨域的

    我们修改刚才的test.ps1更新内容为$a

    PS C:\Users\Terry> $private:a = 1
    PS C:\Users\Terry> notepad .\test.ps1
    PS C:\Users\Terry> . .\test.ps1
    1
    PS C:\Users\Terry> & .\test.ps1

    细心的读者可能发现了,使用&和.调用脚本是不同的.

    &的话,是会重新开打脚本的Scope,而.只作为本地Scope 当前Scope来执行脚本的.

    Script变量,大家可以自己测试啦,其实都很简单的.

    Powershell强类型变量

    Powershell是基于.NET 类型来使用的,.NET 我们知道是使用的强类型,意味着,我们在PS中可以使用同样强大的强类型变量

    PS C:\Users\Terry> [DateTime]$d = "1"
    无法将值“1”转换为类型“System.DateTime”。错误:“该字符串未被识别为有效的 DateTime。”
    所在位置 行:1 字符: 13
    + [DateTime]$d <<<<  = "1"
        + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
        + FullyQualifiedErrorId : RuntimeException

    PS C:\Users\Terry> [Int]$i = 1
    PS C:\Users\Terry> $i="1"
    PS C:\Users\Terry> $i ="a"
    无法将值“a”转换为类型“System.Int32”。错误:“输入字符串的格式不正确。”
    所在位置 行:1 字符: 3
    + $i <<<<  ="a"
        + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
        + FullyQualifiedErrorId : RuntimeException

    使用强类型变量,可以做进一步执行前的类型确认.

    只读或只写其他功能的变量大家可以参考这个连接了,这些功能一般相对来说用的比较少.

    参考Link:http://powershell.com/cs/blogs/ebook/archive/2008/10/22/chapter-3-variables.aspx

  • 相关阅读:
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    迷宫问题 POJ 3984
    UVA 820 Internet Bandwidth (因特网带宽)(最大流)
    UVA 1001 Say Cheese(奶酪里的老鼠)(flod)
    UVA 11105 Semiprime Hnumbers(H半素数)
    UVA 557 Burger(汉堡)(dp+概率)
  • 原文地址:https://www.cnblogs.com/bhtfg538/p/1880999.html
Copyright © 2011-2022 走看看