本帖最后由 Nsqs 于 2023-8-26 11:52 编辑
关于
gm -i {echo "aaa"}
跟
{echo "aaa"}|gm
这里就不得不提到 scriptblock 代码块结构了
如果不做加工处理直接写出来的代码块必须用 & 来调用, & 相当于是bat里的call
因为{}又是一种新的用法,叫代码块
它与bat里的(代码块) 不同
也与PowerShell 里的 @(代码块不同)
@(是一组常规的语法表达式)
{是一种特殊类型,关于他的使用方法实在有点太多了,进阶的用法数不胜数,还不是你目前可以掌握的}
通常一般情况下{}是将一行或多行代码作为代码块,也就是将这个部分的代码作为常规的代码部分处理
举个例子:复制代码 # 在上述例子中,我们会发现$a不能正常使用,通常情况下它应该返回$a=1,所以是不是看起来很奇怪?
# 那么我们检查一下它的类型看看复制代码 # 发现还会报错? 同样的 $a|gm 也会报错
# 代码块中的代码是在一个local 局部域中,因此单独在第二行的$a是一个空的数据,$a的值为null,而gm无法输入null才会导致报错复制代码 - # 由于我们知道在 PowerShell 中可以直接省略write-output,因此可以直接写$a也是可以拥有返回值的
- # 因此更为严谨的写法可以是这样
- {
- $a='hello world'
- Write-Output $a
- }
复制代码 如果我们想得到正确的返回值,那么接下来我们再看几个例子:
例1:- {
- $a='hello world'
- $a
- }
- # 是不是很奇怪?直接运行没有效果
- # 这是因为单独的自定义代码块是不具备输出能力的
- # 就好比我做了一个软件,但我电脑没开机,是用不了的
复制代码
- & {
- $a='hello world'
- $a
- }
- # 为什么加了 & 后能够产生返回值呢?
- # 答: & 就好比bat中的 call 命令
- # 是调用的意思
- # 注意! & 是一个特殊符号,是一个特殊用法,不能直接用 call 比如把bat里的 call 拿过来照搬是不行的
-
- <#
-
- call {
- $a='hello world'
- $a
- }
-
- #>
复制代码 例2:- # 在使用下面这些案例之前,建议关闭 ISE,并重新启动ISE,再使用下面的代码来测试(原因是因为可能会和上面的测试例子变量发生作用域的冲突)
- # 当我们学会使用 & 后,我们真正掌握使用它的方法,比如我们好好的研究一下它还有一个特殊的机制: 作用域
- & {
- $a='hello world'
- }
- $a
- # 以上代码调试后发现$a根本没有返回值,这可咋办?
- # 答: 在{}中的代码只能在{}里使用,或在{}当前域中使用,在{}以外的地方则不能直接读取{}局部域中的变量和数据
复制代码
- # 如果我们想要得到 $a 的值,应该改变作用域,用$Global:设为全局模式
- & {
- $Global:a='hello world'
- }
- $a
复制代码
- # 关于作用域有以下 3 种参数使用:
-
- <#
-
- $Global:
- $Local:
- $Private:
-
- #>
-
- # 以上代码按从高到低来排序他们的使用先后顺序和级别,Global是级别最高的,因此可以在整个脚本存活的生命周期中使用
- # Private是最低的,也是用的最少的,通常情况下,我们的代码如果是写在局部区域,例如变量的赋值,那么大多默认情况都是 Local 局部域
- # 正因如此,我们才可以不需要显式声明$Local:变量名,因为 PowerShell 已经自动为我们声明为局部变量了(如果是在括号内,在括号外会自动为我们声明为 Global)
复制代码 例3:- <#
-
- $Global:
- $Local:
- $Private:
-
- #>
-
- # 有关于在它们三者的使用方法,我简单举个例吧,比如:
- $C='在水果店'
- & { ;$Local:A='小明' ;&{ $Private:B=10}; "$A $C 花了 $B 购买了苹果"}
- & { ;$Local:A='小明' ;&{ $Private:B=10; "$A $C 花了 $B 购买了苹果"}}
- & { ;$Local:A='小明' ; $Private:B=10; & {"$A $C 花了 $B 购买了苹果"}}
- # 在以上三个例子中,变量 $C 是一个 Global 类型 (因为它是在外面赋值的,所以可以在多层嵌套的{}括号中才可以一直都能有返回值)
- # 在上面三个例子中直到最后一个例子可以得出一个结论: Local 无论在多少层内,只要它在上一级域中赋值过,那么在下一级域中都可以得到返回值,但不能出现下面这种情况
- & { & {$Local:A='小明' }; $Private:B=10; & {"$A $C 花了 $B 购买了苹果"}}
复制代码
- & { & {$Local:A='晴天'}; "今天的天气是 $A" }
- & { & { & {$Local:A='晴天'}}; "今天的天气是 $A" }
复制代码
- & { & {$Local:A='暴雨'<# 这是二级域 #>; & { "这是三级域: 今天的天气是 $A" } }; "这是一级域: $A" }
复制代码
- <#
-
- $Global:
- $Local:
- $Private:
-
- #>
-
- '①'
- & { & {$Private:A='暴雨';Write-Host $A <# 这是二级域 #>; & { "这是三级域: 今天的天气是 $A" } }; "这是一级域: $A" }
- # 为了更直观显示,我用了write-host
- '②'
- & { & {$Private:A='暴雨';Write-Host $A <# 这是二级域 #>; & { $Private:A='暴雨';Write-Host $A <# "这是三级域 #> } }; "这是一级域: $A" }
- # 或
- '③'
- & { & {"这是二级域: 今天的天气是 $A"; & { $Private:A='暴雨';Write-Host $A <# "这是三级域 #> } }; "这是一级域: $A" }
复制代码 例4:
# ①- function test1{
- function test2{
- $Private:A='小明'
- }
- test2
- $A
- }
- test1
- # 通过在以上示例的演示,我们发现 $A 是没有正确的返回的,同时也验证了一点,Private的使用公开权限是最低的
复制代码 # ②- # 现在我们换成 Local 继续测试
- function test1{
- function test2{
- $Local:A='小明'
- }
- test2
- $A
- }
- test1
复制代码
- # 但不一样的地方在于,Local可以在上一层域中赋值后在下一层中被正确获取到返回值
- function test1{
- $Local:A='小明'
- function test2{
- $A
- }
- test2
- }
- test1
复制代码
- # 像这种情况 Private 则不具备与 Local 一样的公开级别
- function test1{
- $Private:A='小明'
- function test2{
- $A
- }
- test2
- }
- test1
复制代码 最后关于代码块还有一种很少见的使用方法:
非常规的使用方法- begin{
- # 开始写关于你的...
- }
-
- process{
- # 代码中途的过程...
- }
-
- End{
- # 结束段的代码块...
- }
- # 以上的一般情况都应用在 function 里,也有一部分更进阶的使用方法,就不一一赘述了
复制代码
|