Условное исполнение (&& и ||) в powershell

Уже есть вопрос, касающийся моей проблемы ( можно ли заставить && работать в Powershell?), Но с одним отличием. Мне нужен выход из обеих команд. Смотрите, если я просто бегу:

(command1 -arg1 -arg2) -and (command2 -arg1)

Я не увижу ничего, кроме сообщений stderr. И, как и ожидалось, просто набрав:

command1 -arg1 -arg2 -and command2 -arg1 

Выдает синтаксическую ошибку.

5 ответов

Решение

Попробуй это:

$(command -arg1 -arg2 | Out-Host;$?) -and $(command2 -arg1 | Out-Host;$?)

$() это подвыражение, позволяющее вам указать несколько операторов, включая конвейер. Затем выполните команду и передайте Out-Host так что вы можете видеть это. Следующий оператор (фактический вывод подвыражения) должен вывести $? то есть результат успеха последней команды.


$? отлично работает для нативных команд (консоли exe), но для командлетов оставляет желать лучшего. То есть, $? только кажется, чтобы вернуться $false когда командлет обнаруживает завершающую ошибку. Похоже на $? нужно как минимум три состояния (неудачно, успешно и частично успешно). Так что, если вы используете командлеты, это работает лучше:

$(command -arg1 -arg2 -ev err | Out-Host;!$err) -and 
$(command -arg1 -ev err | Out-Host;!$err)

Этот вид ударов еще. Возможно, что-то вроде этого будет лучше:

function ExecuteUntilError([scriptblock[]]$Scriptblock)
{
    foreach ($sb in $scriptblock)
    {
        $prevErr = $error[0]
        . $sb
        if ($error[0] -ne $prevErr) { break }
    }
}

ExecuteUntilError {command -arg1 -arg2},{command2-arg1}

В Powershell 7 Preview 5 они есть. Я не знаю, почему это было удалено без уведомления или объяснения. https://devblogs.microsoft.com/powershell/powershell-7-preview-5/ Это даст результат обеих команд в соответствии с запрошенным вопросом.

echo 'hello' && echo 'there'
hello
there

echo 'hello' || echo 'there'
hello

Чтобы упростить многошаговые скрипты, где это делается || Выход 1 был бы действительно полезен, я использую что-то вроде:

function ProceedOrExit { 
    if ($?) { echo "Proceed.." } else { echo "Script FAILED! Exiting.."; exit 1 } 
}

doThis; ProceedOrExit
doNext

# or for long doos
doThis
ProceedOrExit
doNext
  • Баш / cmd "s && а также || Операторы управления не имеют эквивалентов PowerShell, и, поскольку вы не можете определить пользовательские операторы в PowerShell, хороших обходных путей нет.

    • | Out-Host Обходной путь в ответе Кейта Хилла строго ограничен в том, что он может только отправлять нормальный вывод команды на консоль (терминал), предотвращая отправку вывода через конвейер или захват в переменную или файл.

Найти справочную информацию в этом моем ответе.

Самое простое решение - использовать

powershell command1 && powershell command2

в оболочке cmd. Конечно, вы не можете использовать это в скрипте.ps1, так что есть такое ограничение.

Немного более длинный путь см. Ниже

попробуй {имя хоста; if ($lastexitcode -eq 0) {ipconfig /all | findstr /i bios}} catch {echo err} finally {}

После выпуска Powershell 7.0 && а также || поддерживаются

https://devblogs.microsoft.com/powershell/announcing-powershell-7-0/

New operators:
  Ternary operator: a ? b : c
  Pipeline chain operators: || and &&
  Null coalescing operators: ?? and ??=
Другие вопросы по тегам