PowerShell学习笔记(1)-基础
PowerShell学习笔记(1):基础
前段时间在知乎上得知Windows下的一款强大的命令行工具PowerShell(原谅我刚刚得知)。 其强大的功能,令人惊叹,兴趣盎然,这么优秀的工具值得我去学习、了解, 虽然我并不是程序猿。我的测试练习环境:win7 PowerShell v1.0
基础内容
命令的概念与术语
基本命令形式如下:
command -parameter1 -parameter2 arg1 arg2
- command:命令名称
- parameter1:开关参数
- parameter2 arg1:带参数变量的参数
- arg2:位置参数
例:Write-Output -InputObject HelloWorld
dir -Recurse -Filter *.ps1 D:\Test,其中开关参数-Recuse指定dir命令显示指定目录及其子目录下的所有文件,-Filter *.ps1过滤出后缀为ps1的文件。
命令分类
PowerShell中的命令可以分为四类:cmdlets、functions、scripts、native Win32 executables。
cmdlet C#源码例子:
[Cmdlet("Write", "InputObject")]
public class MyWriteInputObjectCmdlet : Cmdlet
{
[Parameter]
public string Parameter1;
[Parameter(Mandatory = true, ValueFromPipeline=true)]
public string InputObject;
protected override void ProcessRecord()
{
if (Parameter1 != null)
WriteObject(Parameter1 + ":" + InputObject);
else
WriteObject(InputObject);
}
}
shell函数命令源码例子:
function Write-InputObject
{
param($Parameter1)
process
{
if ($Parameter1)
{
"$Parameter1: $_"
}
else
{
"$_"
}
}
}
shell脚本命令源码例子:
param($Parameter1)
process
{
if ($Parameter1)
{
"$Parameter1:$_"
}
else
{
"$_"
}
}
native Win32 executables也被称作为本地命令,是能被操作系统执行的外部程序。
别名与弹性语法
PowerShell中实现了大量的预定义别名,这些别名可以分为两个基本的类别:transitional别名和convenience别名。使用Get-Command命令可以查看别名的具体的定义。
PowerShell语句解析
双引号、单引号与反引号之间的区别。
转义序列,如下:
`n 换行
`r 回车
`t 水平制表符
`a 警铃
`b 退格
`' 单引号
`" 双引号
'0 空
`` 单反引号
表达式模式与命令模式。在表达式模式中,字符串必须由引号括起,数字始终解析为数字等等。在命令模式中,数字被视为数字,但是其它的参数则被视为字符串(除非参数以$,@,’,”,(开头,当以这些特殊字符开头时,其后的参数被解析为值表达式)。
模式解析例子,如下:
2+2 表达式模式,结果是4.
write-output 2+2 命令模式,结果是 “2+2”.
$a=2+2 表达式模式,变量$a被赋值为值4
write-output (2+2) 表达式模式,2+2被作为表达式计算得到值4,然后作为参数传给write-output
write-output $a 表达式模式,参数前有特殊字符
write-output $a.Equals(4) 表达式模式,$a.Equals(4)计算得到Boolean值True
write-output $a/dir.txt 命令模式,首先参数被计算为4/dir.txt,然后解释器发现并不是一个合法的表达式,然后将其转换为命令模式
有两种语句终止方式:一种是以分号”;”终止,还有一种是以换行符终止。
管线是由管线操作符”|”分割的一系列命令,如:
dir -recurse -filter *.cpp | format-table name,length
格式化与输出。可以通过$PSHOME查看所安装的默认格式数据库的所在路径。
类型处理
基本类型与字面值
PowerShell中的字面值:strings,numbers,array,dictionaries,hashtables。
PowerShell中,字符串是一个16位的Unicode字符序列,其直接由.NET System.String类型直接实现。单引号、双引号字符串,例:"Double quoted string","Single quoted string"。here-strings:以@<quote><newline>开头,并以<quote><newline>@结尾。
数值字面值。PowerShell支持所有基本的.NET数值类型并可在需要时完成不同类型之间的转换。数值字面值如下:
| 数值字面值 | .NET全类型名 | 短类型名 |
|---|---|---|
| 1 | System.Int32 | [int] |
| 10000000 | System.Int64 | [long] |
| 1.1 | System.Double | [double] |
| 1d | System.Decimal | [decimal] |
数值乘数后缀:
| 乘数后缀 | 乘数因子 | 例子 | 等效值 | .NET类型 |
|---|---|---|---|---|
| kb/KB | 1024 | 1KB | 1024 | System.Int32 |
| kb/KB | 1024 | 2.2KB | 2252.8 | System.Double |
| mb/MB | 1024*1024 | 1MB | 1045876 | System.Int32 |
| mb/MB | 1024*1024 | 2.2MB | 2306867.2 | System.Double |
| gb/GB | 1024*1024*1024 | 1Gb | 1073741824 | System.Int32 |
| gb/GB | 1024*1024*1024 | 2.14Gb | 3371549327.36 | System.Double |
创建Hash表,语法以@{开头以}结尾,在分隔符内以定义键值对集,其中键值以=分割,不同的键值对以;分割。例:$test = @{ b1 = "prml"; b2 = "ia"},可以通过$test.b1、$test['b1']访问值,通过$test.keys得到所有键。
PowerShell中创建数组的方式以逗号分割,例$test = 1, 2, 3,对于数字数组还可以使用范围运算符$test = 2 .. 3。PowerShell中数组默认是多态的,即可以在数组中存储任意类型的对象。创建单元素数组$test = ,1,创建空数组$test = @()。
类型名别名:
| PowerShell类型别名 | .NET类型 |
|---|---|
| int[] | System.Int32 |
| [int[]] | System.Int32[] |
| [long] | System.Int64 |
| [long[] | System.Int64[] |
| [string] | System.String |
| [string[]] | System.String[] |
| [char] | System.Char |
| [char[]] | System.Char[] |
| [bool] | System.Boolean |
| [bool[]] | System.Boolean[] |
| [byte] | System.Byte |
| [byte[]] | System.Byte[] |
| [double] | System.Double |
| [double[]] | System.Double[] |
| [decimal] | System.Decimal |
| [decimal[]] | System.Decimal[] |
| [float[]] | System.Single |
| [single] | System.Single |
| [regex] | System.Text.RegularExpressions.Regex |
| [array] | System.Array |
| [xml] | System.Xml.XmlDocument |
| [sriptblock] | System.Management.Automation.ScriptBlock |
| [switch] | System.Management.Automation.SwitchParameter |
| [hashtable] | System.Collections.Hashtable |
| [psobject] | System.Management.Automation.PSObject |
| [type] | System.Type |
| [type[]] | System.Type[] |
访问静态方法,[类名]::属性名,如[math]::cos([math]::pi / 3)。
类型转换,例:[string] [char[]] ( [int[]] [char[]] $s | foreach {$_+1} )。
操作符与表达式
算术运算符
| 运算符 | 描述 |
|---|---|
| + | 两个值(数值、字符串、数组)相加 |
| * | 两个值(数值、字符串、数组)相乘 |
| - | 两个值(数值)相减 |
| / | 两个值(数值)相除 |
| % | 两个值(数值)相模 |
赋值运算符:=、+=、-=、*=、、=、%=。
比较运算符
| 运算符 | 描述 |
|---|---|
| -eq -ceq -ieq | 等于 |
| -ne -cne -ine | 不等于 |
| -gt -cgt -iget | 大于 |
| -ge -cge -ige | 大于等于 |
| -lt -clt -ilt | 小于 |
| -le -cle -ile | 小于等于 |
| -contains -ccontains -icontains | 左侧的集合包含右侧指定的值 |
| -notcontains -cnotcontains -inotcontains | 左侧的集合不包含右侧指定的值 |
注:“c“变体表示大小写敏感,”i“变体表示大小写不敏感.未加限定比较运算符是大小写不敏感的。
模式匹配操作符,有两种匹配类型:通配符表达式(wildcard expressions)、正则表达式(regular expressions)。
通配符模式匹配运算符
| 运算符 | 描述 |
|---|---|
| -like -clike -ilike | 通配符模式匹配,匹配上表达式值则为True |
| -notlike -cnotlike -inotlike | 与-like相反 |
PowerShell中的通配符模式
| 运算符 | 描述 |
|---|---|
* |
匹配字符串中零个或多个字符 |
? |
匹配任意单个字符 |
[<char>-<char>] |
匹配字符区间中的字符 |
[<char><char>..] |
匹配字符集中任意一个字符 |
正则表达式匹配操作符
| 运算符 | 描述 |
|---|---|
| -match -cmatch -imatch | 正则表达式模式匹配 |
| -notmatch -cnotmatch -inotmatch | 与-match相反 |
| -replace -creplace -ireplace | 替换字符串中正则匹配的部分 |
逻辑与按位操作符
| 运算符 | 描述 |
|---|---|
| -and | 逻辑与 |
| -or | 逻辑或 |
| -xor | 异或 |
| -not | 逻辑非 |
| -band | 按位与 |
| -bor | 按位或 |
| -bxor | 按位异或 |
| -bnot | 位非 |
高级操作符与变量
以类型为参数的操作符
| 运算符 | 描述 |
|---|---|
| -is | 操作符左侧的类型与右侧匹配,则表达式为True |
| -isnot | 与-is相反 |
| -as | 将操作符左侧的值转换为右侧指定的类型的值 |
一元操作符:-(将参数转为数值,求负)、+(将参数转换为数值,并返回数值结果)、--(将参数转换为数值,前缀返回新值,后缀返回原值)、++(类似于--)、[<type>](类型转换)、,(一元逗号操作符,创建一个新的单元素数组)。
表达式与分组操作符:(...)、$(...)、@(...)(返回结果是一个数组)。
范围运算符..,生成连续的数值数组的快捷方式。
方法属性操作符:.、::(静态方法)。
格式化运算符:-f是一个二元运算符,运算符左侧是格式化字符串,右侧是需格式化的数组。例:$test = "{2} {1} {0}" -f 1, 2, 3"。
重定向运算符
| 运算符 | 例子 | 描述 |
|---|---|---|
> |
dir > out.txt | 重定向输出到文件。如果文件已存在,则清空当前的内容;如果文件不存在, 则创建该文件 |
>> |
dir >> out.txt | 重定向输出到文件。如果文件已存在,则追加到当前的文件;如果文件不存在,则创建该文件 |
2> |
dir nosuchfile.txt 2> err.txt | 重定向错误流到文件… |
2>> |
dir nosuchfile.txt 2>> err.txt | 重定向错误流到文件… |
2>&1 |
dir nosuchfile.txt 2>&1 | 将错误流写到输出管线 |
变量:PowerShell中不需显示的声明变量,在第一次赋值时自动创建,变量以$为前缀。
流控制语句
if/elseif/else语句,例:
if ($test -gt 100)
{
"It's greater than one hundred"
}
elseif ($test -gt 50)
{
"It's greater than 50"
}
else
{
"It's not very good"
}
while循环,例:
$val = 0
while ($val -ne 3)
{
$val++
Write-Host "The number is $val"
}
do-while循环,例:
$val = 0
do
{
$val++
Write-Host "The number is $val"
} while($val -ne 3)
for循环,例:
for ($i = 0; $i -le 10; $i++)
{
$i;
}
foreach循环,例:
foreach ($i in "hello")
{
$i
}
label,break,continue,例:
for ($i = 0; $i -le 15; $i++)
{
if ($i % 2)
{ continue }
if ($i -eq 10)
{ break }
$i
}
:outer while ($true)
{
while ($true)
{ break outer }
}
switch语句。switch语句是PowerShell中最强大的语句,该语句将模式匹配,分支,迭代组合在一个控制结构中。switch语句语法形式如下:
switch -options ( <pipeline> )
{
<pattern> { <statementList> }
<pattern> { <statementList> }
.....
default { <statementList> }
}
-options:控制怎样匹配,可以是-regex、-wildcard、-match、-case。-case:大小写敏感。-wildcard:通配符。-regex:正则表达式。
<pipeline>:用于产生值控制switch分支。另外,也可以指定序列-file <expr>代替<pipeline>。
pattern/action语句.所有的模式匹配语句都将执行,default语句仅当其他匹配模式都没匹配到时执行。
使用cmdlets进行流控制,例:
dir *.txt | foreach-object {$_.length}
1..10 | where-object { ! ($_ -band 1) }
函数与脚本
PowerShell函数的基本形式如下:
function <name> (<parameter list>) { <statement> }
function subtract ($from, $to) { &from - &to }
function subtract ([int]$from, [int]$to) { $from - $to }
function <name> ($p1=<expr1>, $p2=<expr2>...){<statementList>}
function subtract ($from=2, $to=1) { $from - $to }
参数类型
| 参数类型 | 描述 |
|---|---|
| Switches | Switches参数,例:Get-ChildItem -Recurse |
| Options | Options参数,可带参数值,例:Get-ChildItem -Filter *.txt |
| Arguments | 位置参数,不需要有名字关联位置参数 |
function arith( [switch] $sub, [int] $x, [int] $y )
{
if ($sub)
{
$x - $y
}
else
{
$x + $y
}
}
PowerShell变量的作用域。PowerShell支持四个作用域:全局(global)、本地(local)、私有(private)和脚本(script)。
$global:test = 1 全局变量,在所有的作用域中有效,如果在脚本或者函数中设置了全局变量,即使脚本和函数都运行结束,这个变量也任然有效。
$script:test = 1 脚本变量,只会在脚本内部有效,包括脚本中的函数,一旦脚本运行结束,这个变量就会被回收。
$private:test = 1 私有变量只会在当前作用域有效,不能传递给其它的作用域,只能在当前作用域下读写。
$local:test = 1 局部变量,可以省略修饰符,在当前作用域有效。本地变量能够在其它作用域下读取,但是不能通过其它作用域修改,只有本地作用域可以修改。
return返回函数值,例:
function fact($x)
{
if ($x -lt 2)
{
return 1
}
$x * (fact($x - 1))
}
在管线中使用函数。通过特殊变量$input可以实现在管线中使用函数,这个变量包含一个枚举器以处理输入集合。例:
function sum($para)
{
$total = 0
while ($input.MoveNext())
{
$total += $input.Current.$p
}
$total
}
dir | sum length
过滤器执行一次,并自动实现循环管线中的每个元素。与函数通过$input来访问当前管线对象不同,过滤器有一个特殊的变量$_表示当前的管线对象。过滤器的一般形式与示例如下:
filter <name> (<parameter list>) {<statementList>}
filter sum
{
if ($_ % 2 -eq 0)
{
$_
}
}
cmdlet风格的函数,完整函数语法定义如下:
function <name> (<parameter list>)
{
begin {
<statementList> #第一个管线对象可用之前执行
}
process {
<statementList> #逐一执行每个管线对象
}
end {
<statementList> #所有管线对象执行完后执行
}
}
function test ($x)
{
begin{ $c = 0; "In begin, C is $c, x is $x"}
process{ $c++; "In process, c is $c, x is $x, `$_ is $_"}
end{"In end, c is $c, x is $x"}
}
参考文档
1. 《Windows PowerShell in Action》
2. 使用Windows PowerShell 编写脚本
3. PowerShell-脚本之家
4. Cmdlet Overview
5. PowerShell中文博客

浙公网安备 33010602011771号