为什么没有设置$ MyInvocation.ScriptName和字符串比较?

时间:2017-06-04 17:48:08

标签: powershell duck-typing

这开始是为了让所有四(4)个PowerShell配置文件脚本识别出自己及其位置。

建议使用

$MyInvocation.ScriptName来获取脚本名称,但我还没有看到它只是一个空字符串。不,不是$ null,空('')。这似乎与SO上的许多建议相反。

我的第一个假设是$MyInvocation.ScriptName$null,但事实并非如此。令我惊讶的是,它被认为是-lt 0.将字符串与Int32进行比较的理由是什么?

我确实发现$MyInvocation.InvocationName似乎给出了脚本名称,但没有找到它的目录路径。

PS C:\Users\lit\Documents\PowerShell> Get-Content .\profile.ps1
Write-Host "Current User, All Hosts @ $(Split-Path -Parent $MyInvocation.MyCommand.Definition)\$(Split-Path -Leaf $MyInvocation.MyCommand.Definition)"
Write-Host "`$MyInvocation.ScriptName is $MyInvocation.ScriptName"
Write-Host "`$MyInvocation.ScriptName -eq `$null results in $($MyInvocation.ScriptName -eq $null)"
Write-Host "`$($MyInvocation.ScriptName -eq 0) results in $($MyInvocation.ScriptName -eq 0)"
Write-Host "`$($MyInvocation.ScriptName -lt 0) results in $($MyInvocation.ScriptName -lt 0)"
Write-Host "`$($MyInvocation.ScriptName -eq '') results in $($MyInvocation.ScriptName -eq '')"

Try { '' -eq 0 }
Catch { Write-Host "Caught -lt 0" }

Write-Host $MyInvocation.InvocationName

PS C:\Users\lit\Documents\PowerShell> .\profile.ps1
Current User, All Hosts @ C:\Users\lit\Documents\PowerShell\profile.ps1
$MyInvocation.ScriptName is System.Management.Automation.InvocationInfo.ScriptName
$MyInvocation.ScriptName -eq $null results in False
$(System.Management.Automation.InvocationInfo.ScriptName -eq 0) results in False
$(System.Management.Automation.InvocationInfo.ScriptName -lt 0) results in True
$(System.Management.Automation.InvocationInfo.ScriptName -eq '') results in True
False
.\profile.ps1

JosefZ的建议有效。

PS C:\src\my-powershell> type .\gname.ps1
Write-Host "`$MyInvocation.InvocationName is $((Resolve-Path $MyInvocation.InvocationName).Path)"
Write-Host (Resolve-Path $MyInvocation.InvocationName).Path

PS C:\src\my-powershell> .\gname.ps1
$MyInvocation.InvocationName is C:\src\my-powershell\gname.ps1
C:\src\my-powershell\gname.ps1

我试图收集这些可能的答案,但仍然只有一两个提供所需的答案。 $ MyInvocation.Command始终为$ null,$ MyInvocation.ScriptName始终为空字符串('')。

PS C:\src\t> Get-Content callme.ps1
"=== These two give the full path and invocation path"
Write-Host "$(Split-Path -Parent $MyInvocation.MyCommand.Definition)\$(Split-Path -Leaf $MyInvocation.MyCommand.Definition)"
Write-Host "`$(`$MyInvocation.InvocationName) is $($MyInvocation.InvocationName)"
"=== `$MyInvocation.Command is `$null, but it, and its Source member, do have a type"
Write-Host "`$MyInvocation.Command -eq `$null is $($MyInvocation.Command -eq $null)"
Write-Host "`$MyInvocation.Command is $MyInvocation.Command"
Write-Host "`$(`$MyInvocation.Command) is $($MyInvocation.Command)"
Write-Host "`$MyInvocation.Command.Source is $MyInvocation.Command.Source"
Write-Host "`$(`$MyInvocation.Command.Source) is $($MyInvocation.Command.Source)"
"==="
Write-Host "`$MyInvocation.ScriptName -eq `$null is $($MyInvocation.ScriptName -eq $null)"
Write-Host "`$MyInvocation.ScriptName -eq '' is $($MyInvocation.ScriptName -eq '')"
Write-Host "`$MyInvocation.ScriptName is $MyInvocation.ScriptName"
Write-Host "`$(`$MyInvocation.ScriptName) is $($MyInvocation.ScriptName)"

PS C:\src\t> .\callme.ps1
=== These two give the full path and invocation path
C:\src\t\callme.ps1
$($MyInvocation.InvocationName) is .\callme.ps1
=== $MyInvocation.Command is $null, but it, and its Source member, do have a type
$MyInvocation.Command -eq $null is True
$MyInvocation.Command is System.Management.Automation.InvocationInfo.Command
$($MyInvocation.Command) is
$MyInvocation.Command.Source is System.Management.Automation.InvocationInfo.Command.Source
$($MyInvocation.Command.Source) is
===
$MyInvocation.ScriptName -eq $null is False
$MyInvocation.ScriptName -eq '' is True
$MyInvocation.ScriptName is System.Management.Automation.InvocationInfo.ScriptName
$($MyInvocation.ScriptName) is

1 个答案:

答案 0 :(得分:2)

首先,您的脚本第2行有一个错误。您可能希望将$MyInvocation.ScriptName包裹在$(...)中:

Write-Host "`$MyInvocation.ScriptName is $($MyInvocation.ScriptName)"

接下来,try{}catch{}仅在try{}块中的表达式抛出异常时才起作用。一个简单的比较不会那样做。如果你期望PowerShell抱怨你正在比较尝试不同的类型,那么......它没有。见下文。

来自@PetSerAl的评论是恰当的。从PowerShell提示符运行配置文件时, ScriptName 是调用当前命令的内容。如果您要从另一个脚本调用您的配置文件脚本,您将看到调用脚本名称。根据Matthias的建议,我想您可能想要查看$MyInvocation.MyCommand属性。

最后......

当您将字符串与您正在执行的数字进行比较时,PowerShell会“保护”您并自动将第二个实体(数字)视为字符串,并且您将保留字符串比较:是空字符串"" 小于字符串"0"?为什么,是的。它也小于"-9999"

[PS]> "" -lt -9999
True

所以-9999比什么都重要?让我们切换它们来检查,我们在工作中看到了同样的原则:

[PS]> -9999 -gt ""
False

看似矛盾,除非你记得在每种情况下,比较右边的元素被视为字符串或int,取决于左手边是什么。