Оператор if для переменной пути - powershell - тест true / false

В основном я хочу проверить, существует ли каталог, а затем запустить этот раздел, если не выйти.

У меня есть сценарий:

$Path = Test-Path  c:\temp\First

if ($Path -eq "False")
{
  Write-Host "notthere" -ForegroundColor Yellow
}
elseif ($Path -eq "true")
{
  Write-Host " what the smokes"
}

Но ничего не возвращает.

Это сбивает с толку и вовсе не является хорошей практикой, но просто для того, чтобы вы знали, это сработает: if ("False" -eq $Path) Powershell делает все возможное, чтобы привести второй элемент в сравнении к тому же типу, что и первый элемент. Никогда не делайте этого, но если вы видите это, значит, это работает.

EBGreen 17.07.2018 21:35
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
6 078
4

Ответы 4

Ошибка возникает из-за того, что возвращаемое значение Test-Path является логическим типом.

Следовательно, не сравнивайте его со строковым представлением логического значения, а скорее с фактическими значениями $false / $true. Вот так,

$Path = Test-Path  c:\temp\First

if ($Path -eq $false)
{
    Write-Host "notthere" -ForegroundColor Yellow
}
elseif ($Path -eq $true)
{
    Write-Host " what the smokes"
}

Также обратите внимание, что здесь вы можете использовать оператор else.

В качестве альтернативы вы можете использовать синтаксис, предложенный в ответе @ user9569124,

$Path = Test-Path  c:\temp\First

if (!$Path)
{
    Write-Host "notthere" -ForegroundColor Yellow
}
elseif ($Path)
{
    Write-Host " what the smokes"
}

Хороший вопрос, использование «$ Path» было плохим выбором имени переменной, возможно, «$ IsPath» или чего-то другого.

Mike Q 25.03.2021 16:48

Если не ошибаюсь, можно просто сказать:

if ($Path) ИЛИ ЖЕ if (!$Path)

Но могу ошибаться, потому что не могу проверить банкомат.

Дополнительно доступен командлет Test-Path. К сожалению, я не могу описать разницу или предложить наиболее подходящий метод, не зная случая и сценария.

[ОТредактировано, чтобы уточнить ответ]

$Path = "C:\"
if ($Path)
    {
    write-host "The path or file exists"
    }
else
    {
    write-host "The path or file isn't there silly bear!"
    }

Надеюсь, это добавит ясности. При использовании этого метода командлеты не требуются. Возвращенное логическое значение интерпретируется автоматически и запускает блоки кода, если оно соответствует критериям теста, в данном случае, если существует путь C:\. Это будет верно для файлов с более длинными путями, C:\...\...\...\...\file.txt

Спасибо всем за ответ, не могу поверить, что заключил это в кавычки :) Мне было интересно, есть ли способ проверить имя папки и запустить оператор if для имени? поэтому, если он вызван первым, запустите 1, если он вызвал второй запуск 2 и т. д.

Norrin Rad 17.07.2018 21:38

Это будет оператор переключения Get-Help about_Switch

EBGreen 17.07.2018 21:39

Спасибо парню, который ответил выше. Рад, что помню :) и конечно всегда рад помочь;)

Swift 17.07.2018 21:41

ПРИМЕЧАНИЕ: это неправильный ответ. Test-Path существует не просто так

Mike Q 25.03.2021 15:51

В операции сравнения PowerShell автоматически преобразует второй операнд в тип первого операнда. Поскольку вы сравниваете логическое значение со строкой, строка будет преобразована в логическое значение. Пустые строки будут преобразованы в $false, а непустые строки будут преобразованы в $true. Джеффри Сновер написал статью «Логические значения и операторы» об этих автоматических преобразованиях, которую вы можете проверить для получения дополнительных сведений.

В результате такое поведение имеет (на первый взгляд парадоксальный) эффект, заключающийся в том, что каждое из ваших сравнений будет оценивать значение вашей переменной:

PS C:\> $false -eq 'False'
False
PS C:\> $false -eq 'True'
False
PS C:\> $true -eq 'False'
True
PS C:\> $true -eq 'True'
True

По сути, это означает, что если ваши операторы Test-Path оцениваются как $false, ни один ваших условий будет соответствовать.

Как указывали другие, вы можете решить проблему, сравнив свою переменную с фактическими логическими значениями или просто используя переменную отдельно (поскольку она уже содержит логическое значение, которое можно оценить напрямую). Однако с последним подходом нужно быть осторожным. В этом случае это не будет иметь никакого значения, но в других ситуациях автоматическое преобразование разных значений в одно и то же логическое значение может оказаться нежелательным. Например, $null, 0, пустая строка и пустой массив интерпретируются как логическое значение $false, но могут иметь совершенно разную семантику в зависимости от логики вашего кода.

Кроме того, нет необходимости сначала сохранять результат Test-Path в переменной. Вы можете поместить выражение прямо в условие. А поскольку есть только два возможных значения (файл / папка либо существует, либо не существует), нет необходимости сравнивать дважды, поэтому ваш код может быть сокращен до примерно такого:

if (Test-Path 'C:\temp\First') {
    Write-Host 'what the smokes'
} else {
    Write-Host 'notthere' -ForegroundColor Yellow
}

Чтобы прояснить некоторые вещи, всегда используйте Test-Path (или Test-Path с Leaf для проверки наличия файла).

Примеры, которые я тестировал:

$File = "c:\path\file.exe"
$IsPath = Test-Path -Path $File -PathType Leaf

# using -Not or ! to check if a file doesn't exist
if (-Not(Test-Path -Path $File -PathType Leaf)) {
    Write-Host "1 Not Found!"
}

if (!(Test-Path -Path $File -PathType Leaf)) {
    Write-Host "2 Not Found!"
}

# using -Not or ! to check if a file doesn't exist with the result of Test-Path on a file
If (!$IsPath) {
    Write-Host "3 Not Found!"
}

If (-Not $IsPath) {
    Write-Host "4 Not Found!"
}

# $null checks must be to the left, why not keep same for all?
If ($true -eq $IsPath) {
    Write-Host "1 Found!"
}

# Checking if true shorthand method    
If ($IsPath) {
    Write-Host "2 Found!"
}

if (Test-Path -Path $File -PathType Leaf) {
    Write-Host "3 Found!"
}

Другие вопросы по теме