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

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

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

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

command1 -arg1 -arg2 -and command2 -arg1 

Дает синтаксическую ошибку.

Ответ 1

2019: команда Powershell рассматривает возможность добавления поддержки && в Powershell - примите участие в этом GitHub PR

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

$(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}

Ответ 2

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

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

doThis; ProceedOrExit
doNext

# or for long doos
doThis
ProceedOrExit
doNext

Ответ 3

  • Операторы
  • Bash/cmd && и || не имеют эквивалентов PowerShell, и поскольку вы не можете определить пользовательские операторы в PowerShell, есть no хорошие обходные пути.

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

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

Ответ 4

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

try {
  hostname
  if ($lastexitcode -eq 0) {
    ipconfig /all | findstr /i bios
  }
} catch {
  echo err
} finally {}

Ответ 5

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

powershell command1 && powershell command2

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