Почему $MyInvocation.ScriptName не установлен и сравнение строк?
Это началось с того, что все четыре (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 ответ
Во-первых, у вас есть ошибка в строке 2 вашего скрипта. Вы, вероятно, хотите обернуть $MyInvocation.ScriptName
в $(...)
:
Write-Host "`$MyInvocation.ScriptName is $($MyInvocation.ScriptName)"
Далее try{}catch{}
будет работать только если выражение в try{}
блок выдает исключение. Простое сравнение не делает этого. Если вы ожидали, что PowerShell будет жаловаться, что вы сравниваете, попробуйте разные типы, тогда... это не так. Увидеть ниже.
Комментарий от @PetSerAl уместен. Когда вы запускаете профиль из командной строки PowerShell, ScriptName - это то, что вызывает текущую команду. Если бы вы вызывали скрипт своего профиля из другого скрипта, вы бы увидели имя вызывающего скрипта. Я думаю, вы можете посмотреть на $MyInvocation.MyCommand
собственность вместо этого, согласно предложению Матиаса.
И наконец...
Когда вы сравниваете строку с числом, как вы это делаете, PowerShell "защищает" вас и автоматически обрабатывает второй объект (число) как строку, и вы получаете сравнение строк: это пустая строка ""
меньше чем строка "0"
? Да, да, это так. Это также меньше, чем "-9999"
:
[PS]> "" -lt -9999
True
Так -9999
больше чем ничего? Давайте переключим их, чтобы проверить, и мы увидим тот же принцип в работе:
[PS]> -9999 -gt ""
False
Кажется противоречием, если только вы не помните, что в каждом случае элемент в правой части сравнения обрабатывается как строка или int в зависимости от того, что является левой частью.