Мне нужно запустить службу браузера SQL Server в диспетчере конфигурации SQL Server. Установка не может обнаружить вновь созданный сервис без этого.
То, что должен делать 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
Мы можем использовать метод try catch finally вместо использования & amp; & amp; метод в powershell.
try {hostname} catch {echo err} finally {ipconfig /all | findstr bios}
try
/ catch
здесь бессмысленно, потому что это необходимо только для завершающих ошибок i>, которые не могут вызвать внешняя утилита, такая как hostname
. Ваш код будет безоговорочно i> выполнять обе команды i>.
– mklement0
21 January 2017 в 20:18
Спустя много лет после того, как вопрос был задан первым, позвольте мне кратко изложить положение дел с PowerShell v5.1:
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, поэтому есть надежда, что может быть реализован тот же синтаксис, что и в Bash. (Начиная с PSv5.1, попытка чего-то вроде 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
, напротив, действуют только на выход стандартных команд [success] , потребляют , а затем выводят только логический результат операция; например:
(Get-ChildItem \, nosuchfile) -and 'ok'
Выше:
\
- и интерпретирует его как Boolean ; непустая входная коллекция считается $true
в булевом контексте, поэтому, если есть хотя бы одна запись, выражение оценивается как $true
. Однако информация об ошибке , полученная из несуществующего файла nosuchfile
, проходит через , поскольку ошибки отправляются в отдельный поток. Get-ChildItem \, nosuchfile
возвращает непустой результат успеха, LHS оценивается как $true
, поэтому -and
также оценивает RHS, 'ok'
, но опять же потребляет его вывод и интерпретирует его как логическое значение, которое как непустая строка также оценивается как $true
. -and
равен $true
, который равен (единственный успех) output . Сетевой эффект:
-and
выражение потребляется во время оценки и, следовательно, эффективно hidden . $true
в этот случай (который отображается как True
в терминале в англоязычных системах).
| Out-Null
обязательно хорошая идея. Может быть, труба доWrite-Host
, чтобы мы все еще могли видеть выход? – jpmc26 21 August 2014 в 15:40&&
/||
, так и тернарного условного оператора от языка состоит в том, что они никогда не попадали в верхнюю часть списка - оба были признаны потенциально полезными дополнениями i>: см. здесь для&&
/||
, и по отношению к тернарному оператору сама статья, на которую вы ссылаетесь, начинается с «Одна из вещей, которые мы очень разочаровали в том, что он не может быть отправлен в V1.0, является тернарным оператором. – mklement0 24 January 2017 в 05:34Get-ExitCodeBoolean()
является not i> общей заменой для&&
/||
, поскольку он подавляет регулярный вывод i>, предотвращая его захват в переменной / файле / отправив его по трубопроводу. Красота операторов управления Bash&&
/||
заключается в том, что они не мешают выходным потокам и действуют только на (невидимые) коды выхода i> - и это невозможно (в настоящее время) в PowerShell. Если вы считаете, что это нужно, проголосуйте за него здесь . – mklement0 24 January 2017 в 05:44