Czy mogę pracować w programie PowerShell?

186

&&jest notorycznie trudny do wyszukania w google, ale najlepsze, co znalazłem, to ten artykuł, który mówi, że należy go używać -and.

Niestety nie daje więcej informacji i nie mogę dowiedzieć się, z czym mam zrobić -and(znowu, notorycznie trudna rzecz do wyszukania)

Kontekst, w którym próbuję go użyć, to „wykonaj cmd1, a jeśli się powiedzie, wykonaj cmd2”, w zasadzie to:

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

To powinno być kilka łatwych powtórzeń dla kogoś, kto wie, dzięki!


Edycja: Jeśli chcesz po prostu uruchomić wiele poleceń w jednej linii i nie obchodzi Cię, czy pierwsza zawiedzie, czy nie, możesz użyć ;Do większości moich celów jest to w porządku

Na przykład: kill -n myapp; ./myapp.exe.

Orion Edwards
źródło
PowerShell ma -and i -lub operatory logiczne. Czy operatorzy nie pracują tak, jak tego oczekujesz? Jeśli tak, możesz opublikować wyrażenie tutaj.
Mohit Chakraborty
Zobacz to pytanie, robi to, co chcesz: stackoverflow.com/questions/1917271/ ...
joshperry
2
Kto jest zainteresowany stylem Bash &&i ||staniem się częścią PowerShell: zagłosuj na tę funkcję tutaj .
mklement0
1
Jeśli chodzi o potrzebę wyszukiwania w sieci zapytań z literalnymi (i znaczącymi) symbolami: SymbolHound jest do tego przydatny. Oto kilka przykładów odnoszących się do pytania: powershell && ; powershell - i . Jeśli używasz DuckDuckGo , możesz przeszukiwać SymbolHound przez !sym.
nisavid
3
Aktualizacja z czerwca 2019 r . : Zespół PowerShell wdraża &&i ||! Ważenie na GitHub PR
pilau

Odpowiedzi:

193

W CMD „&&” oznacza „wykonaj polecenie 1, a jeśli się powiedzie, wykonaj polecenie 2”. Używałem go do takich rzeczy jak:

build && run_tests

W PowerShell najbliższą rzeczą, jaką możesz zrobić, jest:

(build) -and (run_tests)

Ma tę samą logikę, ale tekst wyjściowy poleceń zostaje utracony. Ale może ci to wystarczy.

Jeśli robisz to w skrypcie, prawdopodobnie lepiej będzie oddzielić instrukcje, na przykład:

build
if ($?) {
    run_tests
}

2019/11/27 : &&Operator jest teraz dostępny dla programu PowerShell 7 w wersji zapoznawczej 5+ :

PS > echo "Hello!" && echo "World!"
Hello!
World!
Jay Bazuzi
źródło
2
RE: „śmieszne, że usunęliby” - nie lubię myśleć o PowerShell jako o „CMD z usuniętymi głupimi częściami”. is.gd/k92B
Jay Bazuzi,
90
Nie lubię myśleć o PowerShell jako o „CMD z usuniętymi głupimi częściami”. Lubię o tym myśleć jako o „Bash bez żadnych przydatnych bitów”.
Pod
15
Możesz też zrobić to build ; if ($?) { run_tests }w wierszu poleceń.
docwhat
19
Najszybszym sposobem na prawdziwą frustrację podczas nauki PowerShell jest myślenie, że jest to po prostu rozszerzony CMD lub bash. Ma zasadniczo inny model, zwłaszcza jeśli chodzi o dane wejściowe, wyjściowe, orurowanie i wyniki. Zacznij od dobrego samouczka lub przeglądu i nie próbuj zbyt mocno, aby składnia z innych powłok działała. Musisz wziąć to na własnych warunkach.
Mark Meuer
3
Biorąc PowerShell na własnych warunkach, jak uruchomić polecenie, a następnie, jeśli to się powiedzie, uruchomić inne polecenie? Nie sądzę, żeby to narzucało bashpomysły na PowerShell. To podstawowa funkcjonalność powłoki. Jak dotąd najlepsze, jakie widziałem, to to, build ; if ($?) { run_tests }którego będę używać od teraz. Mam nadzieję, że zespół PowerShell doda &&wsparcie!
Nate
28

&& i || znajdowały się na liście rzeczy do wdrożenia (nadal są), ale nie pojawiły się jako kolejna najbardziej użyteczna rzecz do dodania. Powodem jest to, że mamy -AND i -OR. Jeśli uważasz, że jest to ważne, prześlij sugestię na Connect, a rozważymy ją dla V3.

Jeffrey Snover - MSFT
źródło
11
Zarejestrowałem się w Connect i nominowałem się do programu PowerShell, ale nie mogę wymyślić, jak złożyć sugestię. Witryna Connect jest naprawdę złożona i myląca :-(
Orion Edwards
6
Nie mogłem znaleźć wcześniej istniejącego żądania, więc je utworzyłem: connect.microsoft.com/PowerShell/feedback/details/778798/ ...
Andy Arismendi,
22
Wiesz, wciąż pozostaje pytanie, jak napisać odpowiednik, a twoja odpowiedź byłaby o wiele bardziej przydatna, gdybyś dodał przykład użycia -AND
Kyeotic
5
Jest to ważne, ponieważ jest to podstawowe narzędzie do kontroli przepływu używane w systemach starszych niż Windows przez prawie wieczność. Tak przedstawia się JESZCZE KOLEJNA różnica między linuxem a oknami.
airtonix
6
Mam nadzieję, że Jeffrey Snover słucha, ten SO powinien być wystarczającym powodem, aby go teraz wdrożyć. Minęło zbyt dużo czasu, a teraz PowerShell zaczyna pojawiać się w miejscach, na przykład VSCode używa go jako domyślnego terminala w systemie Windows. To jest całkowity ból bez &&, który -andzjada produkt, wcale nie równoważny.
Ciantic
13

Spróbuj tego:

$errorActionPreference='Stop'; csc /t:exe /out:a.exe SomeFile.cs; a.exe
Ivan
źródło
9
Uwaga: Jeśli pierwsze polecenie nie powiedzie się, drugie nadal będzie działać.
BrunoLM
4
Zmienna preferencji $ErrorActionPreferencereguluje tylko sposób traktowania niekańczących błędów zgłaszanych przez polecenia cmdlet ; narzędzia zewnętrzne, takie jak csci a.exenigdy nie zgłaszają takich błędów (odzwierciedlają one tylko stan wyjścia w $?(flaga sukcesu) i $LASTEXITCODE(zgłoszony konkretny kod zakończenia)), więc linia poleceń oznacza bezwarunkowe wykonanie obu poleceń (odpowiednikcmd 's csc /t:exe /out:a.exe SomeFile.cs & a.exe)
mklement0
5

Jeśli twoje polecenie jest dostępne w cmd.exe (coś w rodzaju, python ./script.pyale nie polecenie PowerShell, takie jak ii .(oznacza to otwarcie bieżącego katalogu przez eksplorator)), możesz uruchomić cmd.exe w PowerShell. Składnia jest następująca:

cmd /c "command1 && command2"

Tutaj &&zapewnia składnia cmd opisana w tym pytaniu .

Tomoyuki Aota
źródło
4
Fajnie, uaktualnij do cmd, aby uzyskać dostęp do dodatkowych funkcji.
Bill K
4

Wypróbowałem tę sekwencję poleceń w PowerShell:

Pierwszy test

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

($MyVar -ne $null)zwrócił prawdę i (Get-Content $MyVar)również zwrócił prawdę .

Drugi test

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

($MyVar -ne $null)zwrócił false i do tej pory muszę założyć, że (Get-Content $MyVar)również zwrócił false .

Trzeci test wykazał, że drugi warunek nie został nawet przeanalizowany.

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

($MyVar -ne $null)zwrócił fałsz i udowodnił, że drugi warunek (Get-Content "C:\MyTxt.txt")nigdy nie został spełniony , zwracając fałsz dla całego polecenia.

Cleber Machado
źródło
Masz rację! zachowuje się jak operator &&. Nawet $ () po prawej stronie nie pozwoli tego ocenić!
Falco Alexander
2

Bardzo stare pytanie, ale dla nowicjuszy: być może wersja PowerShell (podobna, ale nie równoważna ), której poszukuje pytanie, ma -andnastępującą postać:

(build_command) -and (run_tests_command)

Francisco Serrano
źródło
1
Może to być poprawne dla twojego przypadku użycia, ale nie zachowuje się jak &&, ponieważ ignoruje kod zakończenia build_command.
Simon Buchan
To zdecydowanie nie jest właściwe postępowanie. Uruchomi drugie polecenie, nawet jeśli pierwsze zawiodło.
Nate
to jest całkowicie błędne. ;jest odpowiednikiem &w cmd i ;bash. To zdecydowanie nie to samo, co &&w cmd
phuclv
Wycisza również STDOUT i STDERR dla obu procesów.
Dragas
0

Zależy to od kontekstu, ale oto przykład „-i” w działaniu:

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

To znaczy, że wszystkie pliki większe niż 10kb znajdują się w katalogu, którego nazwa zaczyna się od „f”.

Matt Hamilton
źródło
1
To nie jest odpowiedź na pierwotne pytanie, które dotyczy wykonywania wielu poleceń.
bdukes
0
if (start-process filename1.exe) {} else {start-process filename2.exe}

To trochę dłużej niż "&&", ale robi to samo bez skryptów i nie jest zbyt trudne do zapamiętania. Lepiej późno niż wcale. :)

Lydell Anderson
źródło
2
Start-Processjest ogólnie niewłaściwym narzędziem do wywoływania narzędzi wiersza poleceń. W szczególności, jak tutaj użyto, Start-Processdziała filename1.exeasynchronicznie w nowym oknie konsoli i nie zwraca nic , co w kontekście Boolean zwraca wartość $false. Nawet jeśli pominiesz Start-Process(i tak powinieneś wywoływać narzędzia wiersza poleceń - bezpośrednio), podejście to nie powiedzie się, ponieważ wynik warunku zależy wtedy od tego, czy narzędzie wygeneruje wyjście na standardowe wyjście, które nie ma gwarantowanego związku z tym, czy udało się czy nie.
mklement0
0

Myślę, że proste stwierdzenie „if” może to osiągnąć. Gdy zobaczyłem, że odpowiedź mkelement0 powyżej tego ostatniego statusu wyjścia jest przechowywana w $?, Zestawiłem następujące elementy:

# 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 }

Więc na przykład op będzie to:

a=(csc /t:exe /out:a.exe SomeFile.cs); $test = $?; if ($test=$true) { a.exe }
slugman
źródło
0

Pełnym odpowiednikiem jest połączenie $LASTEXITCODEi -eq 0:

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

Nie jestem pewien, dlaczego mi się nie if ($?)udało, ale ten zadziałał.

TankorSmash
źródło
-1

Możemy wypróbować to polecenie zamiast metody &&

spróbuj {hostname; if ($ lastexitcode -eq 0) {ipconfig / all | findstr / i bios}} złap {echo err} w końcu {}

Cyberiron
źródło
Nie ma potrzeby używania try/ catch, ponieważ jest potrzebne tylko do przerywania błędów, które zewnętrzne narzędzia, takie jak hostname, ipconfigi findstrnie mogą wywołać. Sprawdzanie $LASTEXITCODEjest potrzebne tylko wtedy, gdy chcesz poznać konkretny kod zakończenia ustawiony przez zewnętrzne narzędzie - abstrakcyjny sukces lub niepowodzenie jest odzwierciedlane $?, podobnie jak w przypadku natywnych poleceń cmdlet.
mklement0
Myślę, że @Cyberiron jest na dobrej drodze. Myślę, że &&w systemie Unix jest bardzo podobny do try / catch, ponieważ nie wymaga zawijania kolejnych poleceń w nowym bloku (tj. }), Gdy zwierasz późniejsze polecenia (pomijasz je). Myślę, że AmpAmpfunkcja / filtr, który rzuca kiedy, if (!?) { throw "last command failed" }byłaby bardzo użytecznym zamiennikiem dla przenoszenia &&do PowerShell. użycie :csc /t:exe /out:a.exe SomeFile.cs; AmpAmp; a.exe
yzorg