PowerShell中的点(。)和&符(&)有什么区别?

时间:2019-02-13 03:11:29

标签: powershell

在PowerShell中,调用cmdlet,函数,脚本文件或可操作程序时,使用点(.)和与号(&)有什么区别?

例如:

. foo.sh1
& foo.sh1

有一个非常相似的问题,已被错误地作为重复项关闭:Differences between ampersand (&) and dot (.) while invoking a PowerShell scriptblock。问题不同,并且关键字和搜索排名完全不同。 What is the `.` shorthand for in a PowerShell pipeline?的答案只能回答一半的问题。

4 个答案:

答案 0 :(得分:2)

  • .&运算符之间的差异仅在调用脚本函数 时才重要(或它们的别名)-对于 cmdlet 外部程序,它们的行为相同。

  • 对于脚本和函数, .&函数定义的作用域方面有所不同, 别名变量

    • &, the call operator ,在 child 范围内执行脚本和功能,这是 典型用途情况:通常希望函数和脚本执行而没有副作用

      • 在调用的脚本/函数中定义的变量,(嵌套的)函数,别名对于调用而言是本地的,并且在脚本退出/函数返回时超出范围。

      • 但是请注意,即使在 child 范围内运行的脚本也会影响调用者的环境,例如使用Set-Location进行更改当前位置,显式修改父作用域(Set-Variable -Scope 1 ...)或全局作用域($global:...)或定义过程级环境变量。

    • ., the dot-sourcing operator ,在当前作用域中执行脚本和功能,通常用于修改调用方的作用域< / em>,添加功能,别名和可能的变量供以后使用 。例如,此机制用于加载初始化交互式会话的$PROFILE文件。

需要注意的是,对于功能(与脚本相反), child current 的引用范围不一定是调用者的范围:如果函数是在 module 中定义的,则引用范围是该模块的作用域域

  • 换句话说:尝试将.源自模块的函数一起使用实际上是没有意义的,因为要修改的作用域是模块的
  • 也就是说,在模块中定义的功能通常并不是在设计时就考虑了点源。

答案 1 :(得分:1)

就像Mathias在this线程中的评论中提到的那样。 &用于调用表达式,&之后的任何内容,.用于在当前范围内调用它,并且通常用于对包含帮助函数的辅助文件进行点源在调用者范围内可用。

答案 2 :(得分:1)

从Windows Powershell in Action的笔记中,您还可以使用调用运算符在模块作用域内运行事物。

# get and variable in module scope
$m = get-module counter
& $m Get-Variable count
& $m Set-Variable count 33

# see func def
& $m Get-Item function:Get-Count

# redefine func in memory
& $m {
  function script:Get-Count
  {
    return $script:count += $increment * 2
  }
}

# get original func def on disk
Import-Module .\counter.psm1 -Force

其他一些事情:

# run with commandinfo object
$d = get-command get-date
& $d

# call anonymous function
& {param($x,$y) $x+$y} 2 5

# same with dot operator
. {param($x,$y) $x+$y} 2 5

答案 3 :(得分:0)

为了隔离并给出清晰的理解,我在解释一种情况。 假设您在MyFunction中有一个名为source.ps1的函数。您希望在另一个脚本( MyCustomScript.ps1

中使用该功能

在MyCustomScript.ps1中放入一行,如下所示,您应该可以使用它。

. path\of\the\source.ps1 

MyFunction

因此,您正在使用自定义脚本中source.ps1中提供的功能。 而&是Powershell中的调用运算符,它将帮助您调用任何外部可执行文件,例如psexec等。

直接(或通过调用操作符)调用命令将创建另一个作用域,称为子作用域,并且在执行该命令后将消失。如果命令正在更改全局变量中的任何值,则在这种情况下,当作用域结束时,更改也会丢失。

为避免此缺点并保留对全局变量所做的任何更改,您可以dot脚本,该脚本将始终在您当前的作用域中执行该脚本。

点源只会在当前范围内运行函数或脚本,而调用运算符(&)将照常运行函数或脚本;但它永远不会添加到当前范围。

希望这可以为何时使用什么提供一个思路。