Bisakah saya && bekerja di Powershell?

186

&&sangat sulit untuk dicari di google, tetapi yang terbaik yang saya temukan adalah artikel ini yang mengatakan untuk digunakan -and.

Sayangnya itu tidak memberikan informasi lebih lanjut, dan saya tidak dapat menemukan apa yang harus saya lakukan dengan -and(sekali lagi, hal yang sangat sulit untuk dicari)

Konteks yang saya coba gunakan adalah "jalankan cmd1, dan jika berhasil, jalankan cmd2", pada dasarnya ini:

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

Ini harus menjadi beberapa poin rep mudah untuk seseorang yang tahu, terima kasih!


Sunting: Jika Anda hanya ingin menjalankan beberapa perintah pada satu baris dan Anda tidak peduli jika yang pertama gagal atau tidak, Anda dapat menggunakan ;Untuk sebagian besar tujuan saya ini baik-baik saja

Sebagai contoh: kill -n myapp; ./myapp.exe.

Orion Edwards
sumber
PowerShell memiliki -dan dan -atau operator logis. Apakah operator tidak bekerja seperti yang Anda harapkan? Jika demikian, Anda dapat memposting ekspresi di sini.
Mohit Chakraborty
Lihat pertanyaan ini, ia melakukan apa yang Anda inginkan: stackoverflow.com/questions/1917271/…
joshperry
2
Siapa pun yang tertarik dengan gaya Bash &&dan ||menjadi bagian dari PowerShell: silakan pilih fitur di sini .
mklement0
1
Mengenai perlunya melakukan pencarian web untuk kueri dengan simbol literal (dan signifikan): SymbolHound berguna untuk ini. Berikut adalah beberapa contoh yang berkaitan dengan pertanyaan: powershell && ; PowerShell -dan . Jika Anda menggunakan DuckDuckGo , Anda dapat mencari di SymbolHound via !sym.
nisavid
3
Pembaruan Juni 2019 : Tim PowerShell sedang menerapkan &&dan ||! Timbang di GitHub PR
pilau

Jawaban:

193

Dalam CMD, '&&' berarti "jalankan perintah 1, dan jika berhasil, jalankan perintah 2". Saya telah menggunakannya untuk hal-hal seperti:

build && run_tests

Di PowerShell, hal terdekat yang dapat Anda lakukan adalah:

(build) -and (run_tests)

Ini memiliki logika yang sama, tetapi teks keluaran dari perintah hilang. Mungkin itu cukup baik untukmu.

Jika Anda melakukan ini dalam skrip, Anda mungkin akan lebih baik memisahkan pernyataan, seperti ini:

build
if ($?) {
    run_tests
}

2019/11/27 : &&Operator sekarang tersedia untuk PowerShell 7 Pratinjau 5+ :

PS > echo "Hello!" && echo "World!"
Hello!
World!

Jay Bazuzi
sumber
2
RE: "konyol bahwa mereka akan menghapus" - Saya tidak suka menganggap PowerShell sebagai "CMD dengan bagian-bagian bodoh dihapus". is.gd/k92B
Jay Bazuzi
90
Saya tidak suka menganggap PowerShell sebagai "CMD dengan bagian-bagian bodoh dihapus". Saya suka menganggapnya sebagai "Bash tanpa bit yang berguna".
Pod
15
Anda juga dapat melakukannya build ; if ($?) { run_tests }di baris perintah.
docwhat
19
Cara tercepat untuk frustrasi nyata ketika mempelajari PowerShell adalah mulai dengan berpikir bahwa itu hanyalah CMD yang diperluas atau bash. Ini memiliki model yang berbeda secara fundamental, epecially ketika datang ke input, output, pipa, dan hasil. Mulailah dengan tutorial atau ikhtisar yang bagus, dan jangan berusaha terlalu keras untuk membuat sintaks dari shell bekerja. Anda harus mengambilnya sendiri.
Mark Meuer
3
Mengambil PowerShell dengan ketentuannya sendiri, bagaimana cara menjalankan perintah dan kemudian, hanya jika perintah itu berhasil, jalankan perintah lain? Saya tidak berpikir itu memaksakan bashide pada PowerShell. Ini fungsi dasar shell. Sejauh ini yang terbaik yang saya lihat adalah build ; if ($?) { run_tests }yang akan saya gunakan mulai sekarang. Saya harap tim PowerShell menambahkan &&dukungan!
Nate
28

&& dan || berada di daftar hal yang harus diimplementasikan (masih ada) tetapi tidak muncul sebagai hal paling berguna berikutnya untuk ditambahkan. Alasannya adalah bahwa kita memiliki -AND dan -OR. Jika menurut Anda ini penting, silakan ajukan saran di Connect dan kami akan mempertimbangkannya untuk V3.

Jeffrey Snover - MSFT
sumber
11
Saya mendaftar di Connect, dan telah menominasikan diri saya untuk PowerShell, tetapi saya tidak tahu cara mengajukan saran. Situs web Connect benar-benar rumit dan membingungkan :-(
Orion Edwards
6
Saya tidak dapat menemukan permintaan yang sudah ada sebelumnya jadi saya membuat permintaan: connect.microsoft.com/PowerShell/feedback/details/778798/…
Andy Arismendi
22
Anda tahu, pertanyaannya masih bagaimana menulis yang setara, dan jawaban Anda akan jauh lebih berguna jika Anda menambahkan contoh menggunakan -AND
Kyeotic
5
Ini penting karena ini adalah alat kontrol aliran dasar yang digunakan pada sistem yang lebih tua dari windows untuk hampir selamanya. Demikianlah YET ANOTHER yang memecahkan perbedaan antara linux dan windows.
airtonix
6
Saya harap Jeffrey Snover mendengarkan, SO ini seharusnya menjadi alasan yang cukup untuk mengimplementasikannya sekarang. Sudah terlalu lama, dan sekarang PowerShell mulai muncul di beberapa tempat, seperti VSCode menggunakannya sebagai terminal default di Windows. Ini adalah rasa sakit total tanpa &&, -andmemakan hasilnya, tidak setara sama sekali.
Ciantic
13

Coba ini:

$errorActionPreference='Stop'; csc /t:exe /out:a.exe SomeFile.cs; a.exe
Ivan
sumber
9
Catatan: Jika perintah pertama gagal, perintah kedua masih akan berjalan.
BrunoLM
4
Variabel preferensi $ErrorActionPreferencehanya mengatur bagaimana kesalahan non-terminasi yang dilaporkan oleh cmdlet diperlakukan; utilitas eksternal seperti cscdan a.exetidak pernah melaporkan kesalahan seperti itu (mereka hanya mencerminkan status keluar mereka di $?(bendera keberhasilan) dan $LASTEXITCODE(kode keluar spesifik dilaporkan)), sehingga baris perintah Anda sama dengan eksekusi tanpa syarat dari kedua perintah (setara cmddengan csc /t:exe /out:a.exe SomeFile.cs & a.exe)
mklement0
5

Jika perintah Anda tersedia di cmd.exe (sesuatu seperti python ./script.pytetapi bukan perintah PowerShell seperti ii .(Ini berarti untuk membuka direktori saat ini dengan explorer)), Anda dapat menjalankan cmd.exe di dalam PowerShell. Sintaksnya seperti ini:

cmd /c "command1 && command2"

Di sini, &&disediakan oleh sintaks cmd yang dijelaskan dalam pertanyaan ini .

Tomoyuki Aota
sumber
4
Bagus, tingkatkan ke cmd untuk mengakses fungsionalitas tambahan itu.
Bill K
4

Saya mencoba urutan perintah ini di PowerShell:

Tes Fisrt

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

($MyVar -ne $null)dikembalikan benar dan (Get-Content $MyVar)juga dikembalikan benar .

Tes kedua

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

($MyVar -ne $null)kembali salah dan sejauh ini saya harus menganggap (Get-Content $MyVar)juga kembali salah .

Tes ketiga membuktikan kondisi kedua bahkan tidak dianalisis.

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

($MyVar -ne $null)kembali salah dan membuktikan kondisi kedua (Get-Content "C:\MyTxt.txt")tidak pernah berjalan, dengan mengembalikan salah pada seluruh perintah.

Cleber Machado
sumber
Anda benar! ini berperilaku sebagai operator &&. Bahkan $ () di sisi kanan tidak akan membiarkan untuk mengevaluasi ini!
Falco Alexander
2

Pertanyaan yang sangat lama, tetapi untuk para pendatang baru: mungkin versi PowerShell (serupa tetapi tidak setara ) yang dicari oleh pertanyaan itu, adalah untuk digunakan -andsebagai berikut:

(build_command) -and (run_tests_command)

Francisco Serrano
sumber
1
Ini mungkin ok untuk kasus penggunaan Anda, tetapi tidak berperilaku seperti itu &&, karena mengabaikan kode keluar build_command.
Simon Buchan
Ini jelas tidak melakukan hal yang benar. Ini akan menjalankan perintah kedua bahkan jika yang pertama gagal.
Nate
ini sepenuhnya salah. ;sama dengan &di cmd dan ;di bash. Ini jelas tidak sama dengan &&di cmd
phuclv
Itu juga mematikan STDOUT dan STDERR untuk kedua proses.
Dragas
0

Itu tergantung pada konteksnya, tetapi inilah contoh "-and" yang sedang beraksi:

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

Jadi itu mendapatkan semua file lebih besar dari 10kb dalam direktori yang nama filenya dimulai dengan "f".

Matt Hamilton
sumber
1
Ini bukan jawaban untuk pertanyaan awal, yaitu tentang menjalankan beberapa perintah.
bdukes
0
if (start-process filename1.exe) {} else {start-process filename2.exe}

Ini sedikit lebih lama dari "&&" tetapi menyelesaikan hal yang sama tanpa skrip dan tidak terlalu sulit untuk diingat. Lebih baik terlambat daripada tidak sama sekali. :)

Lydell Anderson
sumber
2
Start-Processadalah alat yang salah untuk digunakan untuk menjalankan utilitas command-line secara umum. Secara khusus, seperti yang digunakan di sini, Start-Processberjalan secara tidak filename1.exesinkron di jendela konsol baru dan tidak mengembalikan apa pun , yang dalam konteks Boolean dievaluasi $false. Bahkan jika Anda dihilangkan Start-Process(yang adalah bagaimana Anda harus memanggil utilitas baris perintah - secara langsung), pendekatan tersebut akan gagal, karena hasil dari kondisi tergantung pada apakah utilitas menghasilkan output stdout, yang tidak memiliki hubungan jaminan dengan apakah itu berhasil atau tidak.
mklement0
0

Saya pikir pernyataan sederhana jika bisa mencapai ini. Setelah saya melihat respons mkelement0 di atas bahwa status keluar terakhir disimpan dalam $?, Saya menyatukan berikut:

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

Jadi untuk contoh op, itu akan menjadi:

a=(csc /t:exe /out:a.exe SomeFile.cs); $test = $?; if ($test=$true) { a.exe }
siput
sumber
0

Setara verbose adalah menggabungkan $LASTEXITCODEdan -eq 0:

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

Saya tidak yakin mengapa if ($?)tidak bekerja untuk saya, tetapi yang ini berhasil.

TankorSmash
sumber
-1

Kita dapat mencoba perintah ini alih-alih menggunakan metode &&

coba {hostname; if ($ lastexitcode -eq 0) {ipconfig / all | findstr / i bios}} catch {echo err} akhirnya {}

Cyberiron
sumber
Tidak perlu untuk try/ catch, karena hanya diperlukan untuk mengakhiri kesalahan, yang mana utilitas eksternal seperti hostname, ipconfigdan findstrtidak dapat memicu. Memeriksa $LASTEXITCODEhanya diperlukan jika Anda ingin mengetahui kode keluar khusus yang ditetapkan oleh utilitas eksternal - keberhasilan atau kegagalan abstrak tercermin dalam $?, seperti halnya dengan cmdlet asli.
mklement0
Saya pikir @Cyberiron ada di jalur yang benar. Saya pikir &&di Unix sangat mirip try / catch in yang tidak mengharuskan Anda untuk membungkus perintah berikutnya dalam blok baru (yaitu }) ketika Anda melakukan hubungan pendek perintah kemudian (lewati saja). Saya pikir AmpAmpfungsi / filter yang melempar kapan if (!?) { throw "last command failed" }akan menjadi pengganti yang sangat berguna untuk porting &&ke PowerShell. penggunaan :csc /t:exe /out:a.exe SomeFile.cs; AmpAmp; a.exe
yzorg