Могу ли я заставить && работать в Powershell?

186

&&общеизвестно, что его трудно найти в Google, но лучшее, что я нашел, - это статья, в которой говорится, что нужно использовать -and.

К сожалению, это не дает больше информации, и я не могу выяснить, что я должен делать -and(опять же, общеизвестно трудная вещь для поиска)

Контекст, в котором я пытаюсь использовать это: «выполнить cmd1, и в случае успеха выполнить cmd2», в основном это:

csc /t:exe /out:a.exe SomeFile.cs && a.exe

Это должно быть несколько простых повторений для тех, кто знает, спасибо!


Изменить: Если вы просто хотите запустить несколько команд в одной строке, и вам все равно, если первая не работает или нет, вы можете использовать ;Для большинства моих целей это нормально

Например: kill -n myapp; ./myapp.exe.

Орион Эдвардс
источник
PowerShell имеет логические операторы -and и -or. Операторы работают не так, как вы ожидаете? Если это так, вы можете опубликовать выражение здесь.
Мохит Чакраборти
Посмотрите на этот вопрос, он делает то, что вы хотите: stackoverflow.com/questions/1917271/…
joshperry
2
Любой, кто интересуется Bash-стилем &&и ||становится частью PowerShell: пожалуйста, проголосуйте за эту функцию здесь .
mklement0
1
Что касается необходимости выполнять веб-поиск запросов с буквенными (и значимыми) символами: SymbolHound полезен для этого. Вот несколько примеров, относящихся к вопросу: powershell && ; PowerShell-и . Если вы используете DuckDuckGo , вы можете искать SymbolHound через !sym.
Nisavid
3
Обновление за июнь 2019 года : команда PowerShell внедряет &&и ||! Взвешивание в GitHub PR
плов

Ответы:

193

В CMD «&&» означает «выполнить команду 1, а в случае успеха выполнить команду 2». Я использовал его для таких вещей, как:

build && run_tests

В PowerShell самое близкое, что вы можете сделать, это:

(build) -and (run_tests)

У него та же логика, но выходной текст из команд потерян. Может быть, это достаточно хорошо для вас, хотя.

Если вы делаете это в скрипте, вам, вероятно, будет лучше разделить операторы, например так:

build
if ($?) {
    run_tests
}

2019/11/27 : &&оператор теперь доступен для PowerShell 7 Preview 5+ :

PS > echo "Hello!" && echo "World!"
Hello!
World!
Джей Базузи
источник
2
RE: «смешно, что они будут удалены» - мне не нравится думать о PowerShell как «CMD с удаленными глупыми частями». is.gd/k92B
Джей Базузи,
91
Мне не нравится думать о PowerShell как о «CMD с удаленными глупыми частями». Мне нравится думать об этом как "Bash без каких-либо полезных битов".
Pod
15
Вы также можете сделать это build ; if ($?) { run_tests }в командной строке.
что
19
Самый быстрый способ испытать разочарование при изучении PowerShell - начать думать, что это просто расширенный CMD или bash. У него принципиально иная модель, особенно когда речь идет о вводе, выводе, трубопроводе и результатах. Начните с хорошего учебника или обзора, и не пытайтесь слишком усердно заставить работать синтаксис из других оболочек. Вы должны принять это на своих условиях.
Марк Мейер
3
Если взять PowerShell на своих собственных условиях, как мне запустить команду, а затем, только в случае успеха этой команды, запустить другую команду? Я не думаю, что это навязывает bashидеи PowerShell. Это базовая функциональность оболочки. Пока лучшее, что я видел, это то, build ; if ($?) { run_tests }что я буду использовать с этого момента . Я надеюсь, что команда PowerShell добавляет &&поддержку!
Nate
28

&& и || были в списке вещей для реализации (все еще есть), но не появлялись как следующая самая полезная вещь, которую нужно добавить. Причина в том, что у нас есть -AND и -OR. Если вы считаете это важным, пожалуйста, отправьте предложение по Connect, и мы рассмотрим его для V3.

Джеффри Сновер - MSFT
источник
11
Я зарегистрировался в Connect и выдвинул свою кандидатуру на powershell, но не могу понять, как разместить предложение. Сайт Connect действительно сложный и запутанный :-(
Орион Эдвардс,
6
Я не смог найти ранее существовавший запрос, поэтому сделал его: connect.microsoft.com/PowerShell/feedback/details/778798/…
Энди Арисменди,
22
Вы знаете, вопрос все еще в том, как написать эквивалент, и ваш ответ был бы намного более полезным, если бы вы добавили пример использования -AND
Kyeotic
5
Это важно, потому что это основной инструмент управления потоком, который используется в системах старше окон почти вечность. Таким образом, существует еще одна разница между Linux и Windows.
Airtonix
6
Я надеюсь, что Джеффри Сновер прислушивается, этого ДОЛЖНА быть достаточной причиной для его реализации. Это было слишком долго, и теперь PowerShell начинает появляться в некоторых местах, как VSCode использует его в качестве терминала по умолчанию в Windows. Это полная боль без &&, -andсъедает вывод, совсем не эквивалентный.
Ciantic
13

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

$errorActionPreference='Stop'; csc /t:exe /out:a.exe SomeFile.cs; a.exe
Иван
источник
9
Примечание. Если первая команда не будет выполнена, вторая все равно будет выполняться.
BrunoLM
4
Переменная Preference $ErrorActionPreferenceопределяет только то, как обрабатываются неразрывные ошибки, сообщаемые командлетами ; внешние утилиты, такие как cscи a.exeникогда не сообщают о таких ошибках (они отражают только свое состояние выхода в $?(флаг успеха) и $LASTEXITCODE(указанный код выхода)), поэтому ваша командная строка сводится к безусловному выполнению обеих команд (эквивалентно cmd's csc /t:exe /out:a.exe SomeFile.cs & a.exe)
mklement0
5

Если ваша команда доступна в cmd.exe (что-то похожее на python ./script.pyкоманду PowerShell, но не на нее ii .(это означает открыть текущий каталог с помощью проводника)), вы можете запустить cmd.exe в PowerShell. Синтаксис такой:

cmd /c "command1 && command2"

Здесь &&представлен синтаксис cmd, описанный в этом вопросе .

Томоюки Аота
источник
4
Отлично, обновите до cmd для доступа к дополнительным функциям.
Билл К
4

Я попробовал эту последовательность команд в PowerShell:

Первый тест

PS C:\> $MyVar = "C:\MyTxt.txt"
PS C:\> ($MyVar -ne $null) -and (Get-Content $MyVar)
True

($MyVar -ne $null)вернул истину, а (Get-Content $MyVar)также вернул истину .

Второй тест

PS C:\> $MyVar = $null
PS C:\> ($MyVar -ne $null) -and (Get-Content $MyVar)
False

($MyVar -ne $null)вернул ложь и до сих пор я должен предположить, что (Get-Content $MyVar)тоже вернул ложь .

Третий тест доказал, что второе условие даже не анализировалось.

PS C:\> ($MyVar -ne $null) -and (Get-Content "C:\MyTxt.txt")
False

($MyVar -ne $null)вернул false и доказал, что второе условие (Get-Content "C:\MyTxt.txt")никогда не выполнялось, вернув false во всей команде.

Клебер Мачадо
источник
Вы правы! это ведет себя как оператор &&. Даже $ () справа не даст оценить это!
Фалько Александр
2

Очень старый вопрос, но для новичков: возможно, версия PowerShell (похожая, но не эквивалентная ), которую ищет вопрос, заключается -andв следующем:

(build_command) -and (run_tests_command)

Франциско Серрано
источник
1
Это может быть хорошо для вашего случая использования, но оно не ведет себя так &&, как будто игнорирует код выхода build_command.
Саймон Бьюкен
Это определенно не делает правильную вещь. Будет запущена вторая команда, даже если первая не удалась.
Nate
это совершенно неправильно. ;эквивалентно &в cmd и ;в bash. Это определенно не так, как &&в cmd
phuclv
Он также отключает STDOUT и STDERR для обоих процессов.
Драгас
0

Это зависит от контекста, но вот пример «-and» в действии:

get-childitem | where-object { $_.Name.StartsWith("f") -and $_.Length -gt 10kb }

Таким образом, все файлы размером более 10 КБ попадают в каталог, имя файла которого начинается с «f».

Мэтт Гамильтон
источник
1
Это не ответ на первоначальный вопрос, касающийся выполнения нескольких команд.
bdukes
0
if (start-process filename1.exe) {} else {start-process filename2.exe}

Он немного длиннее, чем "&&", но выполняет то же самое без сценариев и не слишком сложен для запоминания. Лучше поздно, чем никогда. :)

Лиделл Андерсон
источник
2
Start-Processнеправильный инструмент, используемый для вызова утилит командной строки в целом. В частности, как здесь используется, асинхронно Start-Processзапускается filename1.exeв новом окне консоли и ничего не возвращает , что в логическом контексте соответствует $false. Даже если вы опустите Start-Process(то есть как вы должны вызывать утилиты командной строки - напрямую), подход будет неудачным, потому что результат условного зависит от того, произвела ли утилита какой-либо вывод stdout, который не имеет гарантированной связи с тем, удалось или нет.
mklement0
0

Я думаю, что простое заявление if может сделать это. Как только я увидел ответ mkelement0 выше, что последний статус выхода хранится в $?, Я собрал следующее:

# Set 1st command to variable
$a=somecommand

# Temp var to store exit status of last command (since we can't write to $?)
$test=$?

# Run Test
if ($test=$true) { 2nd-command }

Так что для примера оп, это будет:

a=(csc /t:exe /out:a.exe SomeFile.cs); $test = $?; if ($test=$true) { a.exe }
slugman
источник
0

Подробный эквивалент состоит в том, чтобы объединить $LASTEXITCODEи -eq 0:

msbuild.exe args; if ($LASTEXITCODE -eq 0) { echo 'it built'; } else { echo 'it failed'; }

Я не уверен, почему if ($?)у меня не получилось, но этот сработал.

TankorSmash
источник
-1

Мы можем попробовать эту команду вместо использования && метода

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

Cyberiron
источник
Нет необходимости в try/ catch, потому что он нужен только для завершения ошибок, какие внешние утилиты, такие какhostname , ipconfigи findstrне могут вызвать. Проверка $LASTEXITCODEнеобходима только в том случае, если вы хотите знать конкретный код выхода, установленный внешней утилитой - абстрактный успех или неудача отражается $?, как и в собственных командлетах.
mklement0
Я думаю, что @Cyberiron на правильном пути. думаю&& Unix во многом похож на try / catch, так как он не требует, чтобы вы заключали последующие команды в новый блок (то есть }), когда вы закорачиваете более поздние команды (пропускайте их). Я думаю, что AmpAmpфункция / фильтр, который выбрасывает, когда if (!?) { throw "last command failed" }будет очень полезной заменой для портирования &&в PowerShell. использование :csc /t:exe /out:a.exe SomeFile.cs; AmpAmp; a.exe
yzorg