Powershell: Bash & amp; & amp; эквивалентный [дубликат]

Мне нужно запустить службу браузера SQL Server в диспетчере конфигурации SQL Server. Установка не может обнаружить вновь созданный сервис без этого.

20
задан mklement0 23 January 2017 в 23:26
поделиться

3 ответа

То, что должен делать Bash, заключается в неявной передаче кода выхода команд в Boolean при передаче логическим операторам. 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
8
ответ дан James Kolpack 19 August 2018 в 16:57
поделиться
  • 1
    Таким образом, для этого нет простой встроенной функциональности? – Andrew J. Brehm 10 March 2010 в 16:15
  • 2
    Нет, не думайте так. Я считаю, что дизайнеры сделали все возможное, чтобы избежать такого угольного использования. На самом деле, нет тройного оператора. Тем не менее, он достаточно мощный, чтобы обеспечить средства, позволяющие легко сворачивать свои собственные. [Д0] blogs.msdn.com/powershell/archive/2006/12/29/… – James Kolpack 10 March 2010 в 16:51
  • 3
    Не уверен, что | Out-Null обязательно хорошая идея. Может быть, труба до Write-Host, чтобы мы все еще могли видеть выход? – jpmc26 21 August 2014 в 15:40
  • 4
    @JamesKolpack: Единственная причина отсутствия как && / ||, так и тернарного условного оператора от языка состоит в том, что они никогда не попадали в верхнюю часть списка - оба были признаны потенциально полезными дополнениями : см. здесь для && / ||, и по отношению к тернарному оператору сама статья, на которую вы ссылаетесь, начинается с «Одна из вещей, которые мы очень разочаровали в том, что он не может быть отправлен в V1.0, является тернарным оператором. – mklement0 24 January 2017 в 05:34
  • 5
    Чтобы быть ясным, Get-ExitCodeBoolean() является not общей заменой для && / ||, поскольку он подавляет регулярный вывод , предотвращая его захват в переменной / файле / отправив его по трубопроводу. Красота операторов управления Bash && / || заключается в том, что они не мешают выходным потокам и действуют только на (невидимые) коды выхода - и это невозможно (в настоящее время) в PowerShell. Если вы считаете, что это нужно, проголосуйте за него здесь . – mklement0 24 January 2017 в 05:44

Мы можем использовать метод try catch finally вместо использования & amp; & amp; метод в powershell.

try {hostname} catch {echo err} finally {ipconfig /all | findstr bios}
0
ответ дан Arount 19 August 2018 в 16:57
поделиться
  • 1
    try / catch здесь бессмысленно, потому что это необходимо только для завершающих ошибок , которые не могут вызвать внешняя утилита, такая как hostname. Ваш код будет безоговорочно выполнять обе команды . – mklement0 21 January 2017 в 20:18

Спустя много лет после того, как вопрос был задан первым, позвольте мне кратко изложить положение дел с PowerShell v5.1:

  • Bash's / cmd 's && и || операторы управления не имеют эквивалентов PowerShell, и поскольку вы не можете определить пользовательские операторы в PowerShell, нет хороших обходных путей: используйте отдельные команды (в отдельных строках или разделенные с ;) и явно проверяйте состояние успеха каждой команды с помощью автоматической переменной $?, например: command1 -arg1 -arg2; if ($?) { command2 -arg1 } # equivalent of && command1 -arg1 -arg2; if (-not $?) { command2 -arg1 } # equivalent of || Ниже приведено описание причин, по которым PowerShell -and и -or обычно являются не решением.
  • Был разговор о добавлении их назад, но, похоже, он никогда не делал вершину списка. Теперь, когда PowerShell вышел с открытым исходным кодом, проблема с g1 была открыта в GitHub . Токены && и || в настоящее время зарезервированы для будущего использования в PowerShell, поэтому есть надежда, что может быть реализован тот же синтаксис, что и в Bash. (Начиная с PSv5.1, попытка чего-то вроде 1 && 1 дает сообщение об ошибке The token '&&' is not a valid statement separator in this version.)

Почему PowerShell -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, напротив, действуют только на выход стандартных команд [success] , потребляют , а затем выводят только логический результат операция; например:

(Get-ChildItem \, nosuchfile) -and 'ok'

Выше:

  • использует и потребляет выход success (стандартный) список \ - и интерпретирует его как Boolean ; непустая входная коллекция считается $true в булевом контексте, поэтому, если есть хотя бы одна запись, выражение оценивается как $true. Однако информация об ошибке , полученная из несуществующего файла nosuchfile , проходит через , поскольку ошибки отправляются в отдельный поток.
  • Учитывая, что Get-ChildItem \, nosuchfile возвращает непустой результат успеха, LHS оценивается как $true, поэтому -and также оценивает RHS, 'ok', но опять же потребляет его вывод и интерпретирует его как логическое значение, которое как непустая строка также оценивается как $true.
  • Таким образом, общий результат выражения -and равен $true, который равен (единственный успех) output .

Сетевой эффект:

  • Выход успеха с обеих сторон -and выражение потребляется во время оценки и, следовательно, эффективно hidden .
  • Вывод выражения (успех) выражения - это его логический результат, который является $true в этот случай (который отображается как True в терминале в англоязычных системах).
14
ответ дан Community 19 August 2018 в 16:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: