Powershell 语句块 4


脚本块是一种特殊的命令模式。一个脚本块可以包含许多的 Powershell命令和语句。它通常使用大括号定义。最小最短的脚本块,可能就是一对大括号,中间什么也没有。可以使用之前的调用操作符“&”执行脚本块:

PS E:> & {"当前时间:" + (get-date) }
当前时间:08/08/2012 22:30:24

将命令行作为整体执行

可能你已经意识到,在Powershell中,调用操作符不但可以执行一条单独的命令,还可以执行”命令行”.最方便的方式就是讲你的命令行放在一个语句块中,作为整体。在之前的文章中说过,调用操作符只能执行一条命令,但是借助语句块的这把利器,可以让调用操作符执行,多条Powershell命令,例如:

PS E:> & {$files=ls;Write-Host "文件数:" $files.Count }
文件数: 29
执行表达式

另外还有一条Powershell命令集,Invoke-Expression,这条命令的逻辑就是将一条字符串传递给调用操作符。例如:

PS E:> Invoke-Expression 'Get-Process | Where-Object { $_.Name -like "e*"}'

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    332      29    12280      24264   154     1.40   3236 egui
    386      32    78624      85508   183            1884 ekrn
    284      22     8980      17048    99            1920 EvtEng
   1000      89    55520      83280   355    23.24   2848 explorer

这里有一点需要注意,在传递给invoke-expression的字符串使用了单引号,单引号可以防止变量被替换。如果上面的命令使用了双引号,会先去解释$_.name,但是当前作用域中,$_.Name 为null,所以结果不是期望的。

管道中的foreach-object语句块

管道中的foreach-object本身后面也会带语句块,针对数组中的每一个元素分别传递给语句块处理。 例如:

 Get-Process | ForEach-Object { $_.name }
 
条件和循环中的语句块

在条件语句中,如果条件满足,做一件事,条件不满足做另外一件事,这一件事或者另外一件事本身应当是一个整体,尽管本身可能包含了许多命令和语句。所以会把它们放在一个语句块中。

在循环语句中,如果条件满足循环做一件事,这一件事本身,也是一个整体。 这里就不举例了。

函数本身是一个已命名的语句块

为什么把函数和语句块归结在一起呢?请看下面的例子。

#定义一个函数
Function SayHello([string]$people="everyone")
{
	write-host "Hello, $people ”
}

#通过函数调用
SayHello "Mosser"
Hello, Mosser

#通过语句块调用
$func=function:SayHello
$scriptblocks

param([string]$people="everyone")
write-host "Hello, $people ”

& $scriptblocks
Hello, everyone

构建语句块

既然函数只是被命令的语句块,那是不是也可以通过语句块就能实现函数的特性呢?接下来就验证一下吧。

传递参数给语句块

在函数中可以传递参数:

Function SayHello([string]$people="everyone")
{
	write-host "Hello, $people ”
}

能否在语句块中也传递参数?

& { param($people="everyone") write-host "Hello, $people ” } "Mosser"
Hello, Mosser

定义和传递参数一次性完成,有点匿名函数的味道。

Begin, Process, End 管道语句块

之前讲过定义函数也可以按照Begin, Process, End的结构,这样尤其可以实时处理管道数据。那能不能也直接通过语句块定义呢?

get-process | select -last 5 | & {
begin {
"开始准备环境"
}
process
{
 $_.Name
}
end {
"开始清理环境"
}
}
#输出结果为:
开始准备环境
wlcommsvc
WLIDSVC
WLIDSVCM
WmiPrvSE
XDict
开始清理环境
验证变量

函数中的所有变量都是内置的,属于函数定义域。除非你指定给一个全局变量赋值。首先通过函数实现:

function Test
{
$value1 = 10
$global:value2 = 20
}
Test
$value1
$value2
20

那语句块也支持吗?例如:

& { $value1 = 10; $global:value2 = 20 }
$value1
$value2
20

通过语句块可以实现函数的3个特性,再一次印证了函数确实是命名的语句块。

本文链接: https://www.pstips.net/powershell-using-scriptblocks.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

回复 heqichang 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

4 条评论 “Powershell 语句块