Почему присвоение true переменной не будет оценивать true? - PullRequest
2 голосов
/ 09 октября 2019
$test = true
if($test) {
  Write-Output "true"
} else {
  Write-Output "false"
}

Вывод «ложь», но почему? Я назначаю true и false свойствам COM-объекта, и он, кажется, работает правильно ... Я что-то не так делаю? Когда целесообразно использовать true против $true в PowerShell?

Редактировать: Некоторые пользователи упоминали, что я должен видеть ошибку, но я не вижу. Я пробовал в PowerShell 2.0 (Windows 7) и PowerShell 4.0 (Windows 8.1). И true и false меняют свойства COM, как я уже сказал.

Редактировать: Оказывается, мы назначали true свойствам COM, но они фактически получили false. У нас есть программы gnuwin32 на нашем пути, и две из этих программ имеют значение true и false:

C:\gnuwin32\bin\true.EXE
C:\gnuwin32\bin\false.EXE

Так что на этих компьютерах что-то вроде $x = true запускает команду C:\gnuwin32\bin\true.EXE, которая не имеет выходных данных и$x равно нулю. Никто никогда не догадывался, что свойства com, предназначенные для установки в true, на самом деле не были установлены таким образом.

Ответ, помеченный как правильный, объясняет «истину», и что значение было фактически нулевым значением, котороечто помогло мне разобраться.

Ответы [ 3 ]

3 голосов
/ 09 октября 2019

Поскольку вопрос , почему это происходит, позвольте мне углубиться в детали в моем ответе


if($test) проверяет что-то, называемое правдивым . По сути, он преобразует результат выражения в логическое значение, а затем проверяет, является ли оно истинным или ложным. Вы можете прочитать больше об этом в этом ответе .

В вашем случае, как Мартин Брандл упомянул в своем полезном ответе , пытаясь присвоить $test = true волю (вв большинстве случаев) приводит к исключению, но код продолжает выполняться .

ПРИМЕЧАНИЕ : оператор в полужирный не всегдаЗначение true, так как оно зависит от $ErrorActionPreferrence, но в вашем случае это правда, поскольку вы упомянули, что вы получаете выходные данные.

После сбоя назначения значение $test равно$null - вы можете проверить это следующим образом:

$test -eq $null

$null является значением Фолси, поэтому выражение в вашем if() оценивается как $false и выполняется код после ключевого слова else, следовательно,False в вашем выводе.

1 голос
/ 09 октября 2019

Ваша первая строка $test = true, вероятно, выдаст следующее исключение (за исключением того, что для $ErrorActionPreference установлено значение SilentlyContinue ):

true : The term 'true' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:9
+ $test = true
+         ~~~~
    + CategoryInfo          : ObjectNotFound: (true:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Если вы не хотите $test чтобы быть логическим со значением 1 (true), тогда вы должны присвоить его следующим образом: $test = $true.

Почему вывод 'false'?

Как уже упоминалось, $test = true сгенерирует исключение, поэтому $test не объявлено / не определено. Я бы порекомендовал вам установить $ErrorActionPreference в Continue или Stop , чтобы перехватывать ошибки такого типа.

0 голосов
/ 11 октября 2019

Unix "true" и "false" команды отличаются от powershell $ true и $ false. Unix только устанавливают код выхода, но не дают вывода. Переменные powershell дают логический вывод. Вот обходной путь, который проверяет код завершения предыдущей команды:

$test = $(true.exe; $?) # $test gets set to boolean True
if($test) {
  Write-Output "true"
} else {
  Write-Output "false"
}
...