В Bash я могу легко сделать что-то вроде
command1 && command2 || command3
что означает запуск команды 1, и если command1 успешно запускает команду2, и если command1 не запускает command3.
Что эквивалентно в PowerShell?
В Bash я могу легко сделать что-то вроде
command1 && command2 || command3
что означает запуск команды 1, и если command1 успешно запускает команду2, и если command1 не запускает command3.
Что эквивалентно в PowerShell?
То, что должно выполняться Bash, - это неявное отбрасывание кода выхода команд на логическое значение при передаче логическим операторам. PowerShell этого не делает, но может быть сделана функция для обертывания команды и создания такого же поведения:
> function Get-ExitBoolean($cmd) { & $cmd | Out-Null; $? }
($? - это bool, содержащий успех последнего кода выхода)
Учитывая два командных файла:
#pass.cmd
exit
и
#fail.cmd
exit /b 200
... поведение может быть проверено:
> if (Get-ExitBoolean .\pass.cmd) { write pass } else { write fail }
pass
> if (Get-ExitBoolean .\fail.cmd) { write pass } else { write fail }
fail
Логические операторы должны оцениваться так же, как в Bash. Сначала установите псевдоним:
> Set-Alias geb Get-ExitBoolean
Тест:
> (geb .\pass.cmd) -and (geb .\fail.cmd)
False
> (geb .\fail.cmd) -and (geb .\pass.cmd)
False
> (geb .\pass.cmd) -and (geb .\pass.cmd)
True
> (geb .\pass.cmd) -or (geb .\fail.cmd)
True
Обновление: && и || наконец-то приходят в PowerShell (Core) - см. этот RFC, предположительно в какой-то момент после v7.
Спустя много лет после того, как вопрос был впервые задан, позвольте мне обобщить состояние дел в PowerShell v5.1:
Операторы управления Bash/cmd && и || не имеют эквивалентов PowerShell, и поскольку вы не можете определить пользовательские операторы в PowerShell, не существует хороших обходных путей:
Используйте отдельные команды (в отдельных строках или через ;) и явно проверяйте статус успешности каждой команды с помощью автоматической переменной $?, например:
command1 -arg1 -arg2; if ($?) { command2 -arg1 } # equivalent of &&
command1 -arg1 -arg2; if (-not $?) { command2 -arg1 } # equivalent of ||
Ниже показано, почему PowerShell -and и -or, как правило, не являются решением.
Некоторое время назад велись разговоры о добавлении их, но, похоже, он так и не занял первое место в списке.
&& и || в настоящее время зарезервированы для будущего использования в PowerShell, поэтому есть надежда, что тот же синтаксис, что и в Bash, может быть реализован.1 && 1 выдает сообщение об ошибке The token '&&' is not a valid statement separator in this version.)-and и -or не могут заменить && и ||: операторы управления Bash && (короткое замыкание логического И) и || (короткое замыкание логического ИЛИ) неявно проверяют состояние успешности команд по их кодам выхода, не влияя на их выходные потоки; например.:
ls / nosuchfile && echo 'ok'
Все, что выводит ls - и вывод stdout (файлы в /), и вывод stderr (сообщение об ошибке при попытке доступа к несуществующему файлу nosuchfile) - пропускается, но && проверяет (невидимый) код выхода команды ls, чтобы решить, должна ли быть выполнена команда echo - RHS оператора управления &&.
ls сообщает о коде выхода 1 в этом случае о сбое сигнализации - поскольку файл nosuchfile не существует - поэтому && решает, что ls произошел сбой, и, применяя короткое замыкание, решает, что echo не нужно выполнять команду.
Обратите внимание, что именно код выхода 0 сигнализирует об успехе в мире cmd.exe и bash, тогда как любой ненулевой код выхода означает сбой.
Другими словами: Bash && и || работают полностью независимо от вывода команд и влияют только на статус успешности команд.
PowerShell -and и -or, напротив, действуют только на стандартный (успешный) вывод команд, потребляют его, а затем выводят только логический результат операции; например.:
(Get-ChildItem \, nosuchfile) -and 'ok'
Выше:
использует и использует (стандартный) вывод успешной работы - список \ - и интерпретирует его как логическое значение; непустая коллекция входных данных считается $true в логическом контексте, поэтому, если существует хотя бы одна запись, выражение оценивается как $true.
nosuchfile, передается, поскольку ошибки отправляются в отдельный поток.Учитывая, что Get-ChildItem \, nosuchfile возвращает непустые выходные данные об успешном завершении, LHS оценивается как $true, поэтому -and также оценивает RHS, 'ok', но, опять же, использует свой вывод и интерпретирует его как логическое значение, которое, как непустая строка, также оценивается как $true.
Таким образом, общий результат выражения -and - $true, который является (единственным успехом) выводом.
чистый эффект :
Результаты success output с обеих сторон выражения -and используются во время оценки и поэтому эффективно скрываются.
Вывод только для выражения (успешное завершение) является его логическим результатом, который в данном случае равен $true (который отображается как True в терминале в англоязычных системах).
Мы можем использовать метод try catch finally вместо использования && метод в powershell.
try {hostname} catch {echo err} finally {ipconfig /all | findstr bios}
Вы можете сделать что-то вроде этого, где вы скрываете логический вывод с помощью [void] и получаете только побочный эффект. В этом случае, если $ a или $ b равны нулю, $ c присваивается $ result. Назначение может быть выражением.
$a = ''
$b = ''
$c = 'hi'
[void](
  ($result = $a) -or
  ($result = $b) -or
  ($result = $c))
$result
выход
hi