Chinaunix首页 | 论坛 | 博客
  • 博客访问: 619519
  • 博文数量: 233
  • 博客积分: 2221
  • 博客等级: 大尉
  • 技术积分: 3184
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-16 14:01
个人简介

瓜瓜派的瓜瓜

文章分类

全部博文(233)

文章存档

2013年(28)

2012年(197)

2011年(8)

分类: IT业界

2012-01-09 13:19:11

本文主要和大家描述一下关于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
阅读(983) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~