【问题标题】:What is the difference between dot (.) and ampersand (&) in PowerShell?PowerShell 中的点 (.) 和与号 (&) 有什么区别?
【发布时间】:2022-04-05 08:57:03
【问题描述】:

在 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? 上的答案只回答了一半的问题。

【问题讨论】:

  • 您是否阅读并比较了相关文档部分(Call operator &Dot sourcing operator .)?那里的信息是否不足以回答您的问题?如果是,如何回答?
  • @BACON:感谢您提供文档链接。正如 - 可悲 - 典型的那样,官方文档并没有讲述完整的故事。

标签: powershell


【解决方案1】:
  • .& 运算符之间的区别在调用 PowerShell 脚本函数(或它们的别名) - 对于 cmdlet外部程序,它们的行为相同。

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

    • &, the call operator,在 child 范围内执行脚本和函数,这是典型用例 : 通常期望函数和脚本执行没有副作用

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

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

    • ., the dot-sourcing operator,在当前范围中执行脚本和函数,通常用于修改调用者的范围,通过添加函数、别名和可能的变量供以后使用。例如,此机制用于加载初始化交互式会话的$PROFILE 文件。

需要注意的是,对于 functions(相对于脚本),childcurrent 的参考范围不一定是 调用者的范围:如果函数是在模块中定义的,则引用范围是该模块的范围域

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

【讨论】:

    【解决方案2】:

    就像 this 线程中的评论提到的 Mathias 一样。 & 用于调用 & 之后的表达式,. 用于在当前范围内调用它,通常用于点源一个帮助文件,该文件包含使其在调用者范围内可用的函数。

    【讨论】:

      【解决方案3】:

      您还可以使用调用运算符在模块范围内运行东西,来自 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
      

      【讨论】:

        【解决方案4】:

        为了区分并给出清晰的理解,我正在解释一个场景。 假设您在 source.ps1 中有一个名为 MyFunction 的函数。并且您希望在另一个脚本中使用该函数(MyCustomScript.ps1)

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

        . path\of\the\source.ps1 
        
        MyFunction
        

        因此,您正在使用自定义脚本中 source.ps1 中存在的函数。 而& 是 Powershell 中的调用运算符,它将帮助您调用任何外部可执行文件,例如 psexec 和其他。

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

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

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

        希望这可以让您了解何时使用什么。

        【讨论】:

          猜你喜欢
          • 2015-07-26
          • 2014-10-29
          • 2017-06-01
          • 2012-04-28
          • 1970-01-01
          • 1970-01-01
          • 2019-10-24
          • 2020-11-27
          相关资源
          最近更新 更多