为什么不设置 $MyInvocation.ScriptName 和字符串比较?
Why is $MyInvocation.ScriptName not set and string comparisons?
这开始是为了让所有四 (4) 个 PowerShell 配置文件脚本识别它们自己和它们的位置。
$MyInvocation.ScriptName
被建议用于获取脚本名称,但我还没有看到它不是空字符串。不,不是 $null,空的 ('')。这似乎与这里关于 SO 的许多建议背道而驰。
我的第一个假设是 $MyInvocation.ScriptName
是 $null
,但事实并非如此。然而,令我惊讶的是,它被认为是 -lt 0。将 String 与 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
首先,您的脚本的第 2 行存在错误。您可能想将 $MyInvocation.ScriptName
包装在 $(...)
:
中
Write-Host "`$MyInvocation.ScriptName is $($MyInvocation.ScriptName)"
接下来,try{}catch{}
只有在 try{}
块中的表达式抛出异常时才会起作用。简单的比较并不能做到这一点。如果您希望 PowerShell 抱怨您正在比较尝试不同的类型,那么......它不会。见下文。
@PetSerAl 的评论是中肯的。当您从 PowerShell 提示符 运行 配置文件时,ScriptName 就是调用当前命令的内容。如果您要从 另一个 脚本调用您的配置文件脚本,您会看到调用脚本名称。我认为您可能想按照 Matthias 的建议查看 $MyInvocation.MyCommand
属性。
最后...
当您按照自己的方式将字符串与数字进行比较时,PowerShell "protects" 会自动将第二个实体(数字)视为字符串,然后您将进行字符串比较:空字符串 ""
是否小于 字符串 "0"
?为什么,是的。也小于"-9999"
:
[PS]> "" -lt -9999
True
所以 -9999
聊胜于无?让我们把它们换过来检查一下,我们看到同样的原理在起作用:
[PS]> -9999 -gt ""
False
这看似矛盾,除非您记得在每种情况下比较右侧的元素都被视为字符串或整数,具体取决于左侧是什么。
这开始是为了让所有四 (4) 个 PowerShell 配置文件脚本识别它们自己和它们的位置。
$MyInvocation.ScriptName
被建议用于获取脚本名称,但我还没有看到它不是空字符串。不,不是 $null,空的 ('')。这似乎与这里关于 SO 的许多建议背道而驰。
我的第一个假设是 $MyInvocation.ScriptName
是 $null
,但事实并非如此。然而,令我惊讶的是,它被认为是 -lt 0。将 String 与 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
首先,您的脚本的第 2 行存在错误。您可能想将 $MyInvocation.ScriptName
包装在 $(...)
:
Write-Host "`$MyInvocation.ScriptName is $($MyInvocation.ScriptName)"
接下来,try{}catch{}
只有在 try{}
块中的表达式抛出异常时才会起作用。简单的比较并不能做到这一点。如果您希望 PowerShell 抱怨您正在比较尝试不同的类型,那么......它不会。见下文。
@PetSerAl 的评论是中肯的。当您从 PowerShell 提示符 运行 配置文件时,ScriptName 就是调用当前命令的内容。如果您要从 另一个 脚本调用您的配置文件脚本,您会看到调用脚本名称。我认为您可能想按照 Matthias 的建议查看 $MyInvocation.MyCommand
属性。
最后...
当您按照自己的方式将字符串与数字进行比较时,PowerShell "protects" 会自动将第二个实体(数字)视为字符串,然后您将进行字符串比较:空字符串 ""
是否小于 字符串 "0"
?为什么,是的。也小于"-9999"
:
[PS]> "" -lt -9999
True
所以 -9999
聊胜于无?让我们把它们换过来检查一下,我们看到同样的原理在起作用:
[PS]> -9999 -gt ""
False
这看似矛盾,除非您记得在每种情况下比较右侧的元素都被视为字符串或整数,具体取决于左侧是什么。