根据从另一个脚本或 shell 调用来区分脚本中的代码

Differentiate code in script depending on called from another script or shell

我正在尝试区分脚本 A 中的代码,当脚本 A 是从另一个脚本 B 调用时与它自己运行时的代码。

脚本 A

$callingScript = $MyInvocation.MyCommand.Source | Split-Path -Leaf
if($callingScript -eq "$($MyInvocation.MyCommand.Name)"){
    # Script is run from Shell
}else{
    # Skript is called from script B.ps1
}

脚本 B

(...)
& "$($PSScriptRoot)\A.ps1" 

结果总是$callingScript是A。ps1并且Name也是A。 任何想法如何完成这个?

那个应该有效:
脚本-A.ps1

if ($MyInvocation.InvocationName -eq $MyInvocation.MyCommand.Source)
{
    Out-Host -InputObject ('Script startet with: ' + $MyInvocation.InvocationName)
}
else
{
    Out-Host -InputObject ('Script startet with: ' + $MyInvocation.ScriptName)
}

脚本-B.ps1

& C:\Temp\Script-A.ps1

输出:

PS C:\> C:\Temp\Script-A.ps1
Script startet with: C:\Temp\Script-A.ps1
PS C:\> C:\Temp\Script-B.ps1
Script startet with: C:\Temp\Script-B.ps1

实际上我会使用输入参数(开关)来识别大小写,因为只有在 ISE 中使用 F5 执行文件或直接 powershell.exe 中的脚本 运行 时,上述方法才有效。

在脚本中,$MyInvocation.PSCommandPath 包含:

  • 调用脚本的完整路径 - 如果有的话。

  • 否则,空字符串;也就是说,如果直接从 PowerShell 提示符或通过 CLI - powershell.exe (Windows PowerShell) / [= 直接调用脚本,则返回空字符串13=](PowerShell 核心)。

因此:

if (-not $MyInvocation.PSCommandPath){
  # Script was called from the PowerShell prompt or via the PowerShell CLI.
  'DIRECT invocation'
}
else {
  # Script was called from the script whose path is reflected in
  # $MyInvocation.PSCommandPath
  'Invocation VIA SCRIPT'
}

:

  • 据我所知,$MyInvocation.ScriptName 包含与 $MyInvocation.PSCommandPath 相同的信息;我选择上面的后者是为了与 $PSCommandPath

  • 对称
  • 函数 在这些属性方面被忽略了——只有 封闭脚本 才是重要的。

    • 然而,Get-PSCallStack的输出也反映了函数。

    • 如果您 dot-source 脚本 (. ./script.ps1) 定义一个函数 调用您的目标脚本,并且您稍后调用该函数,$MyInvocation.PSCommandPath 仍将反映原始 脚本 - 无论您从何处调用该函数 (即使您直接从提示符或通过另一个脚本调用它)。