Чи можу я отримати && працювати в Powershell?


186

&&сумно важко шукати в Google, але найкраще, що я знайшов, - це стаття, в якій говориться про використання -and.

На жаль, це не дає більше інформації, і я не можу з’ясувати, з чим я маю займатися -and(знову ж таки, горезвісно важкий предмет пошуку)

Контекст, в якому я намагаюся його використовувати, - це "виконати cmd1, а якщо це вдасться, виконати cmd2", в основному це:

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

Це має бути декілька простих реп-пунктів тому, хто знає, дякую!


Редагувати: Якщо ви просто хочете запустити кілька команд в одному рядку, і вам не байдуже, чи не вдасться перший чи ні, ви можете використовувати ;для більшості моїх цілей це добре

Наприклад: kill -n myapp; ./myapp.exe.


PowerShell має логічний та логічний оператори. Чи оператори не працюють так, як ви їх очікуєте? Якщо так, ви можете опублікувати вираз тут.
— Мохіт Чакраборті

Дивіться це питання, він робить те , що ви хочете: stackoverflow.com/questions/1917271 / ...
— joshperry

2
Хто цікавиться стилем баш &&та ||стає частиною PowerShell: будь ласка, проголосуйте за цю функцію тут .
— mklement0

1
Щодо необхідності здійснення веб-пошуку запитів з буквальними (і значущими) символами: SymbolHound корисний для цього. Ось кілька прикладів, які стосуються питання: 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
— Джей Базузі,

90
Мені не подобається вважати PowerShell "CMD із видаленими дурними частинами". Мені подобається думати про це як "Bash без жодного корисного шматочка".
— Под

15
Ви також можете зробити це і build ; if ($?) { run_tests }в командному рядку.
— docwhat

19
Найшвидший шлях до справжніх розладів при навчанні PowerShell - це почати з думки, що це просто розширений CMD або баш. Вона має принципово іншу модель, epecially , коли справа доходить до введення, виведення, трубопроводів, і результатів. Почніть з хорошого підручника чи огляду, і не намагайтеся занадто сильно змусити синтаксис з інших оболонок працювати. Ви повинні прийняти це на власних умовах.
— Марк Меуер

3
Приймаючи PowerShell за власними умовами, як я запускаю команду, а потім, лише якщо ця команда успішна, виконувати іншу команду? Я не думаю, що це нав'язує bashідеї PowerShell. Це основна функція оболонки. Поки що найкраще, що я бачив, - build ; if ($?) { run_tests }це я буду використовувати зараз. Я сподіваюся, що команда PowerShell додає &&підтримку!
— Нейт

28

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


11
Я зареєструвався на Connect і висунув свою кандидатуру на повноваження, але не можу зрозуміти, як розмістити пропозицію. Веб-сайт Connect справді складний і заплутаний :-(
— Orion Edwards

6
Я не зміг знайти попереднього запиту, тому зробив такий: connect.microsoft.com/PowerShell/feedback/details/778798/…
— Енді Арісменді

22
Ви знаєте, питання все ще полягає в тому, як написати еквівалент, і ваша відповідь була б набагато кориснішою, якщо ви додали приклад використання -AND
— Kyeotic

5
Це важливо, тому що це основний інструмент контролю потоку, який використовується у системах, старих вікон майже вічність. Таким чином, представлено ТАКОЖ РОЗБІР різницю між Linux та Windows.
— airtonix

6
Я сподіваюсь, що Джеффрі Сновер слухає, це ОГ повинно бути достатньою підставою для його впровадження до цього часу. Минуло вже занадто довго, і тепер PowerShell починає спливати місцями, як VSCode використовує його як термінал за замовчуванням у Windows. Це загальний біль без &&, -andз'їдає вихід, а не еквівалентний зовсім.
— Сіантік

13

Спробуйте це:

$errorActionPreference='Stop'; csc /t:exe /out:a.exe SomeFile.cs; a.exe

9
Примітка: Якщо перша команда не вдається, друга все ще буде запущена.
— BrunoLM

4
Перемінна налаштування $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)повернув неправду і довів, що друга умова (Get-Content "C:\MyTxt.txt")ніколи не виконувалася, повертаючи помилку на всю команду.


Ви маєте рацію! це поводиться як оператор &&. Навіть $ () з правого боку не дасть оцінити це!
— Фалько Олександр

2

Дуже старе питання, але для новачків: можливо, для версії PowerShell (аналогічної, але не еквівалентної ), яку шукає питання, слід використовувати -andнаступне:

(build_command) -and (run_tests_command)


1
Це може бути нормально для вашого випадку використання, але він не веде себе так &&, що ігнорує вихідний код build_command.
— Саймон Бучан

Це точно не робиться правильно. Вона виконає другу команду, навіть якщо перша не вдалася.
— Нейт

це абсолютно неправильно. ;- еквівалент &в cmd і ;bash. Це точно не те саме, що &&в cmd
— phuclv

Він також ігнорує STDOUT та STDERR для обох процесів.
— Драгас

0

Це залежить від контексту, але ось приклад дії "-і" в дії:

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

Я думаю, що просто, якщо заява може це досягти. Після того, як я побачив відповідь 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 }

0

Дослідний еквівалент - поєднувати $LASTEXITCODEта -eq 0:

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

Я не впевнений, чому if ($?)не працював для мене, але цей зробив.


-1

Ми можемо спробувати цю команду замість методу &&

спробуйте {ім'я хоста; if ($ lastexitcode -eq 0) {ipconfig / all | findstr / i bios}} зловити {echo err} нарешті {}


Немає потреби в try/ catch, бо вона потрібна лише для завершення помилок, які зовнішні утиліти, такі як hostname, ipconfigі findstrне можуть запустити. Перевірка $LASTEXITCODEпотрібна лише в тому випадку, якщо ви хочете знати конкретний код виходу, встановлений зовнішньою утилітою - абстрактний успіх чи збій відображаються $?, як і в рідних командлетах.
— mklement0

Я думаю, що @Cyberiron на вірному шляху. Я думаю&& в Unix дуже схоже на пробувати / ловити в тому, що це не вимагає, щоб ви загортали наступні команди в новий блок (тобто }), коли ви коротко замикаєте пізніші команди (пропускаєте їх). Я думаю, що AmpAmpфункція / фільтр, який видає, коли if (!?) { throw "last command failed" }буде дуже корисною заміною для перенесення &&до PowerShell. використання :csc /t:exe /out:a.exe SomeFile.cs; AmpAmp; a.exe
— yzorg
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.