1

帮助文档说脚本将以“点源”模式执行,但事实并非如此。为什么?

看了帮助文档的全文,找不到原因,就来求助了。

PS> PowerShell.exe -File '.\dot-source-test.ps1'
PS> $theValue
PS> . '.\dot-source-test.ps1'
PS> $theValue
theValue
PS>

'dot-source-test.ps1' 的内容是$theValue = 'theValue'.

如果 File 的值是文件路径,则脚本在本地范围(“dot-sourced”)中运行,以便脚本创建的函数和变量在当前会话中可用。

about_PowerShell_exe - PowerShell | 微软文档

4

2 回答 2

2

为防止概念混淆:

为了对脚本进行点源,即直接在调用者的作用域中执行它(与默认的子作用域相反),以便调用者看到脚本的变量、函数定义……:

  • 当前的PowerShell 会话.中,直接使用dot-sourcing 运算符:

    # Dot-source in the caller's scope.
    # When executed at the prompt in an interactive PowerShell session,
    # the script's definitions become globally available.
    . '.\dot-source-test.ps1'
    
  • 通过Windows PowerShell CLIpowershell.exe [ 1]

    • 注意:您以这种方式执行的任何 dot-sourcing 都仅限于运行的子进程及其PowerShell会话;它对调用者的会话没有影响。powershell.exe

    • 通过 CLI 进行点源仅在两种情况下有意义

      • 场景 A:您通过(可能是位置隐含的)-Command( -c) 参数传递命令,该参数依赖于必须首先从脚本文件中获取点源的定义,并且您希望会话在命令完成执行后自动退出。

      • 场景 B:您正在进入一个(可能是嵌套的)交互式PowerShell 会话,您希望从脚本文件中点源(预加载)定义;与任何交互式会话一样,您需要手动退出它,通常使用exit.

场景 A:预加载定义,执行依赖它们的命令,然后退出:

以下启动一个(新的)PowerShell 会话,如下所示:

  • 脚本文件.\dot-source-test.ps1是点源的,它$theValue在调用者(这里:全局)范围内定义变量。

  • 的值$theValue是输出。

  • 完成命令后会自动退出新会话。

PS> powershell -c '. .\dot-source-test.ps1; $theValue'
theValue

场景 B:使用预加载的定义进入(新的)交互式会话:

只需添加-noexit开关以进入脚本文件已被点源的交互式会话:.\dot-source-test.ps1

powershell -noexit -c '. .\dot-source-test.ps1'
# You're now  in a (new) interactive session in which $theValue is defined,
# and which you must eventually exit manually.

笔记:

  • 如果既-File没有指定也没有指定命令(通过显式或隐含的-Command/ -c),-noexit则为隐含的。
    因为-c这里需要点源,所以-noexit 必须指定以保持会话打开。

  • 虽然使用-File点源代替 -powershell -noexit -File '.\dot-source-test.ps1'也可以,但出于概念原因,我建议避免使用它

    • 虽然技术上讲,传递给的脚本-File在新会话中是点源的,但这是(a)出乎意料的,因为从会话内部执行的脚本不是(它们在子范围内运行)和(b)到目前为止最典型的用例-File是执行给定的脚本然后退出——在这种情况下,点源的方面是无关紧要的。

    • 因此,最好将此行为视为实现细节,不幸的是CLI 帮助如此突出地提及它 - 导致引发此问题的混乱。


[1] 这同样适用于PowerShell [Core] 7+ CLI pwsh,除了它默认为-File而不是
-Command.

于 2020-12-27T16:04:47.013 回答
2

这是关于文件路径通过命令行传递的方式。在命令提示符中使用时请参见以下示例。(test.ps1 包含该行$theValue = 'theValue'

CMD 窗口示例

在不使用“-File”切换的情况下,它的处理方式不同,作为要传递给被触发的 PowerShell 进程的参数。

在 PowerShell 中调用时看到同样的情况。

PowerShell 窗口示例

您引用的特定部分在需要使用的“-File”切换下。

如果 File 的值为“-”,则从标准输入中读取命令文本。运行 powershell -File - 没有重定向标准输入会启动一个常规会话。这与根本不指定 File 参数相同。

如果 File 的值是文件路径,则脚本在本地范围(“dot-sourced”)中运行,以便脚本创建的函数和变量在当前会话中可用。

(来源:Microsoft Docs > 关于 PowerShell.exe

于 2020-12-27T05:09:15.953 回答