about_Parsing

Deskripsi singkat

Menjelaskan cara PowerShell mengurai perintah.

Deskripsi panjang

Saat Anda memasukkan perintah di prompt perintah, PowerShell memecah teks perintah menjadi serangkaian segmen yang disebut token lalu menentukan cara menginterpretasikan setiap token.

Misalnya, jika Anda mengetik:

Write-Host book

PowerShell memecah perintah menjadi dua token, Write-Host dan book, dan menafsirkan setiap token secara independen menggunakan salah satu dari dua mode penguraian utama: mode ekspresi dan mode argumen.

Catatan

Saat PowerShell menguraikan input perintah, PowerShell mencoba menyelesaikan nama perintah ke cmdlet atau executable asli. Jika nama perintah tidak memiliki kecocokan yang tepat, PowerShell akan menambahkan Get- sebelumnya ke perintah sebagai kata kerja default. Misalnya, PowerShell mengurai Service sebagai Get-Service. Tidak disarankan untuk menggunakan fitur ini karena alasan berikut:

  • Ini tidak efisien. Hal ini menyebabkan PowerShell mencari beberapa kali.
  • Program eksternal dengan nama yang sama diselesaikan terlebih dahulu, sehingga Anda mungkin tidak menjalankan cmdlet yang dimaksudkan.
  • Get-Help dan Get-Command tidak mengenali nama tanpa kata kerja.
  • Nama perintah mungkin merupakan kata yang dipesan atau kata kunci bahasa. Process adalah keduanya, dan tidak dapat diselesaikan ke Get-Process.

Mode ekspresi

Mode ekspresi ditujukan untuk menggabungkan ekspresi, diperlukan untuk manipulasi nilai dalam bahasa skrip. Ekspresi adalah representasi nilai dalam sintaks PowerShell, dan bisa sederhana atau komposit, misalnya:

Ekspresi harfiah adalah representasi langsung dari nilai-nilainya:

'hello'
32

Ekspresi variabel membawa nilai variabel yang mereka referensikan:

$x
$script:path

Operator menggabungkan ekspresi lain untuk evaluasi:

-12
-not $Quiet
3 + 7
$input.Length -gt 1
  • Literal string karakter harus dimuat dalam tanda kutip.
  • Angka diperlakukan sebagai nilai numerik daripada sebagai serangkaian karakter (kecuali lolos).
  • Operator, termasuk operator unary seperti - dan -not dan operator biner seperti + dan -gt, ditafsirkan sebagai operator dan menerapkan operasi masing-masing pada argumen mereka (operand).
  • Ekspresi atribut dan konversi diurai sebagai ekspresi dan diterapkan ke ekspresi subordinat. Misalnya: [int] '7'.
  • Referensi variabel dievaluasi ke nilainya tetapi splatting dilarang dan menyebabkan kesalahan pengurai.
  • Hal lain diperlakukan sebagai perintah untuk dipanggil.

Mode argumen

Saat mengurai, PowerShell pertama-tama terlihat menginterpretasikan input sebagai ekspresi. Tetapi ketika pemanggilan perintah ditemui, penguraian berlanjut dalam mode argumen. Jika Anda memiliki argumen yang berisi spasi, seperti jalur, maka Anda harus mengapit nilai argumen tersebut dalam tanda kutip.

Mode argumen dirancang untuk mengurai argumen dan parameter untuk perintah di lingkungan shell. Semua input diperlakukan sebagai string yang dapat diperluas kecuali menggunakan salah satu sintaks berikut:

  • Tanda dolar ($) diikuti dengan nama variabel memulai referensi variabel, jika tidak, itu ditafsirkan sebagai bagian dari string yang dapat diperluas. Referensi variabel dapat mencakup akses anggota atau pengindeksan.

    • Karakter tambahan yang mengikuti referensi variabel sederhana, seperti $HOME, dianggap sebagai bagian dari argumen yang sama. Sertakan nama variabel dalam kurung kurawal ({}) untuk memisahkannya dari karakter berikutnya. Contohnya,${HOME}.
    • Saat referensi variabel menyertakan akses anggota, karakter tambahan pertama dianggap sebagai awal argumen baru. Misalnya $HOME.Length-more menghasilkan dua argumen: nilai $HOME.Length dan string literal -more.
  • Tanda kutip (' dan ") memulai string

  • Kurung kurawal ({}) memulai blok skrip baru

  • Commas (,) memperkenalkan daftar yang diteruskan sebagai array, kecuali perintah yang dipanggil adalah aplikasi asli, dalam hal ini mereka ditafsirkan sebagai bagian dari string yang dapat diperluas. Koma awal, berturut-turut, atau berikutnya tidak didukung.

  • Tanda kurung (()) memulai ekspresi baru

  • Operator subekspresi ($()) memulai ekspresi yang disematkan

  • Awal pada tanda (@) memulai sintaks ekspresi seperti percikan (@args), array (@(1,2,3)), dan literal tabel hash (@{a=1;b=2}).

  • (), $(), dan @() di awal token buat konteks penguraian baru yang dapat berisi ekspresi atau perintah berlapis.

    • Ketika diikuti oleh karakter tambahan, karakter tambahan pertama dianggap sebagai awal argumen baru yang terpisah.
    • Ketika didahului oleh literal $() yang tidak dikutip berfungsi seperti string yang dapat diperluas, () memulai argumen baru yang merupakan ekspresi, dan @() diambil sebagai harfiah @ dengan () memulai argumen baru yang merupakan ekspresi.
  • Segala sesuatu yang lain diperlakukan sebagai string yang dapat diperluas, kecuali metakarakter yang masih perlu melarikan diri. Lihat Menangani karakter khusus.

    • Metakarakter mode argumen (karakter dengan arti sinaktik khusus) adalah: <space> ' " ` , ; ( ) { } | & < > @ #. Dari jumlah tersebut, < > @ # hanya khusus pada awal token.
  • Token stop-parsing (--%) mengubah interpretasi semua argumen yang tersisa. Untuk informasi selengkapnya, lihat bagian hentikan penguraian token di bawah ini.

Contoh

Tabel berikut ini menyediakan beberapa contoh token yang diproses dalam mode ekspresi dan mode argumen dan evaluasi token tersebut. Untuk contoh ini, nilai variabel $a adalah 4.

Contoh Mode Hasil
2 Ekspresi 2 (bilangan bulat)
`2 Ekspresi "2" (perintah)
Write-Output 2 Ekspresi 2 (bilangan bulat)
2+2 Ekspresi 4 (bilangan bulat)
Write-Output 2+2 Argumen "2+2" (string)
Write-Output(2+2) Ekspresi 4 (bilangan bulat)
$a Ekspresi 4 (bilangan bulat)
Write-Output $a Ekspresi 4 (bilangan bulat)
$a+2 Ekspresi 6 (bilangan bulat)
Write-Output $a+2 Argumen "4+2" (string)
$- Argumen "$-" (perintah)
Write-Output $- Argumen "$-" (string)
a$a Ekspresi "a$a" (perintah)
Write-Output a$a Argumen "a4" (string)
a'$a' Ekspresi "a$a" (perintah)
Write-Output a'$a' Argumen "a$a" (string)
a"$a" Ekspresi "a$a" (perintah)
Write-Output a"$a" Argumen "a4" (string)
a$(2) Ekspresi "a$(2)" (perintah)
Write-Output a$(2) Argumen "a2" (string)

Setiap token dapat ditafsirkan sebagai semacam jenis objek, seperti Boolean atau String. PowerShell mencoba menentukan jenis objek dari ekspresi. Jenis objek tergantung pada jenis parameter yang diharapkan perintah dan pada apakah PowerShell tahu cara mengonversi argumen ke jenis yang benar. Tabel berikut ini memperlihatkan beberapa contoh jenis yang ditetapkan ke nilai yang dikembalikan oleh ekspresi.

Contoh Mode Hasil
Write-Output !1 argumen "!1" (string)
Write-Output (!1) expression False (Boolean)
Write-Output (2) expression 2 (bilangan bulat)
Set-Variable AB A,B argumen 'A','B' (array)
CMD /CECHO A,B argumen 'A,B' (string)
CMD /CECHO $AB expression 'A B' (array)
CMD /CECHO :$AB argumen ':A B' (string)

Menangani karakter khusus

Karakter backtick (`) dapat digunakan untuk melepaskan karakter khusus apa pun dalam ekspresi. Ini paling berguna untuk melarikan diri dari metakarakter mode argumen yang ingin Anda gunakan sebagai karakter harfiah daripada sebagai metacharacter. Misalnya, untuk menggunakan tanda dolar ($) sebagai harfiah dalam string yang dapat diperluas:

"The value of `$ErrorActionPreference is '$ErrorActionPreference'."
The value of $ErrorActionPreference is 'Continue'.

Kelanjutan baris

Karakter backtick juga dapat digunakan di akhir baris untuk memungkinkan Anda melanjutkan input pada baris berikutnya. Ini meningkatkan keterbacaan perintah yang mengambil beberapa parameter dengan nama panjang dan nilai argumen. Contohnya:

New-AzVm `
    -ResourceGroupName "myResourceGroupVM" `
    -Name "myVM" `
    -Location "EastUS" `
    -VirtualNetworkName "myVnet" `
    -SubnetName "mySubnet" `
    -SecurityGroupName "myNetworkSecurityGroup" `
    -PublicIpAddressName "myPublicIpAddress" `
    -Credential $cred

Namun, Anda harus menghindari penggunaan kelanjutan baris.

  • Karakter backtick bisa sulit dilihat dan mudah dilupakan.
  • Ruang ekstra setelah backtick memutus kelanjutan baris. Karena ruang sulit untuk melihat mungkin sulit untuk menemukan kesalahan.

PowerShell menyediakan beberapa cara garis jeda pada titik alami dalam sintaks.

  • Setelah karakter pipa (|)
  • Setelah operator biner (+, -, -eq, dll.)
  • Setelah koma (,) dalam array
  • Setelah membuka karakter seperti [, , {(

Untuk set parameter besar, gunakan splatting sebagai gantinya. Contohnya:

$parameters = @{
    ResourceGroupName = "myResourceGroupVM"
    Name = "myVM"
    Location = "EastUS"
    VirtualNetworkName = "myVnet"
    SubnetName = "mySubnet"
    SecurityGroupName = "myNetworkSecurityGroup"
    PublicIpAddressName = "myPublicIpAddress"
    Credential = $cred
}
New-AzVm @parameters

Meneruskan argumen ke perintah asli

Saat menjalankan perintah asli dari PowerShell, argumen pertama kali diurai oleh PowerShell. Argumen yang diurai kemudian digabungkan ke dalam satu string dengan setiap parameter yang dipisahkan oleh spasi.

Misalnya, perintah berikut memanggil icacls.exe program.

icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F

Untuk menjalankan perintah ini di PowerShell 2.0, Anda harus menggunakan karakter escape untuk mencegah PowerShell salah menafsirkan tanda kurung.

icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F

Token stop-parsing

Dimulai di PowerShell 3.0, Anda dapat menggunakan token stop-parsing (--%) untuk menghentikan PowerShell menginterpretasikan input sebagai perintah atau ekspresi PowerShell.

Catatan

Token stop-parsing hanya ditujukan untuk menggunakan perintah asli pada platform Windows.

Saat memanggil perintah asli, letakkan token stop-parsing sebelum argumen program. Teknik ini jauh lebih mudah daripada menggunakan karakter escape untuk mencegah misinterpretasi.

Ketika menemukan token stop-parsing, PowerShell memperlakukan karakter yang tersisa di baris sebagai harfiah. Satu-satunya interpretasi yang dilakukannya adalah mengganti nilai untuk variabel lingkungan yang menggunakan notasi Windows standar, seperti %USERPROFILE%.

icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F

PowerShell mengirimkan string perintah berikut ke icacls.exe program:

X:\VMS /grant Dom\HVAdmin:(CI)(OI)F

Token stop-parsing hanya efektif hingga karakter baris baru atau alur berikutnya. Anda tidak dapat menggunakan karakter kelanjutan baris (`) untuk memperluas efeknya atau menggunakan pemisah perintah (;) untuk mengakhiri efeknya.

%variable% Selain referensi variabel lingkungan, Anda tidak dapat menyematkan elemen dinamis lainnya dalam perintah. % Melarikan diri karakter sebagai %%, cara yang dapat Anda lakukan di dalam file batch, tidak didukung. %<name>% token terus diperluas. Jika <name> tidak merujuk ke variabel lingkungan yang ditentukan, token diteruskan apa adanya.

Anda tidak dapat menggunakan pengalihan aliran (seperti >file.txt) karena diteruskan verbatim sebagai argumen ke perintah target.

Dalam contoh berikut, langkah pertama menjalankan perintah tanpa menggunakan token stop-parsing. PowerShell mengevaluasi string yang dikutip dan meneruskan nilai (tanpa tanda kutip) ke cmd.exe, yang menghasilkan kesalahan.

PS> cmd /c echo "a|b"
'b' is not recognized as an internal or external command,
operable program or batch file.
PS> cmd /c --% echo "a|b"
"a|b"

Catatan

Token stop-parsing tidak diperlukan saat menggunakan cmdlet PowerShell. Namun, mungkin berguna untuk meneruskan argumen ke fungsi PowerShell yang dirancang untuk memanggil perintah asli dengan argumen tersebut.

Meneruskan argumen yang berisi karakter kutipan

Beberapa perintah asli mengharapkan argumen yang berisi karakter kutipan. PowerShell 7.3 mengubah cara baris perintah diurai untuk perintah asli.

Perhatian

Perilaku baru adalah perubahan yang melanggar dari perilaku Window PowerShell 5.1. Ini dapat merusak skrip dan otomatisasi yang mengatasi berbagai masalah saat memanggil aplikasi asli. Gunakan token stop-parsing (--%) atau Start-Process cmdlet untuk menghindari argumen asli yang melewati saat diperlukan.

Variabel preferensi baru $PSNativeCommandArgumentPassing mengontrol perilaku ini. Variabel ini memungkinkan Anda untuk memilih perilaku saat runtime. Nilai yang valid adalah Legacy, Standard, dan Windows. Perilaku defaultnya adalah platform khusus. Pada platform Windows, pengaturan defaultnya adalah Windows dan platform non-Windows default ke Standard.

Legacy adalah perilaku bersejarah. Perilaku Windows mode dan Standard sama kecuali, dalam Windows mode, pemanggilan file berikut secara otomatis menggunakan Legacy argumen gaya yang melewati.

  • cmd.exe
  • cscript.exe
  • wscript.exe
  • diakhir dengan .bat
  • diakhir dengan .cmd
  • diakhir dengan .js
  • diakhir dengan .vbs
  • diakhir dengan .wsf

$PSNativeCommandArgumentPassing Jika diatur ke atau LegacyStandard, pengurai tidak memeriksa file-file ini.

Catatan

Contoh berikut menggunakan alat ini TestExe.exe . Anda dapat membuat TestExe dari kode sumber. Lihat TestExe di repositori sumber PowerShell.

Perilaku baru yang disediakan oleh perubahan ini:

  • String harfiah atau dapat diperluas dengan tanda kutip yang disematkan, tanda kutip sekarang dipertahankan:

    PS> $a = 'a" "b'
    PS> TestExe -echoargs $a 'c" "d' e" "f
    Arg 0 is <a" "b>
    Arg 1 is <c" "d>
    Arg 2 is <e f>
    
  • String kosong sebagai argumen sekarang dipertahankan:

    PS> TestExe -echoargs '' a b ''
    Arg 0 is <>
    Arg 1 is <a>
    Arg 2 is <b>
    Arg 3 is <>
    

Tujuan dari contoh ini adalah untuk meneruskan jalur direktori (dengan spasi dan tanda kutip) "C:\Program Files (x86)\Microsoft\" ke perintah asli sehingga menerima jalur sebagai string yang dikutip.

Dalam Windows mode atau Standard , contoh berikut menghasilkan hasil yang diharapkan:

TestExe -echoargs """${env:ProgramFiles(x86)}\Microsoft\"""
TestExe -echoargs '"C:\Program Files (x86)\Microsoft\"'

Untuk mendapatkan hasil yang sama dalam Legacy mode, Anda harus keluar dari tanda kutip atau menggunakan token stop-parsing (--%):

TestExe -echoargs """""${env:ProgramFiles(x86)}\Microsoft\\"""""
TestExe -echoargs "\""C:\Program Files (x86)\Microsoft\\"""
TestExe -echoargs --% ""\""C:\Program Files (x86)\Microsoft\\"\"""
TestExe -echoargs --% """C:\Program Files (x86)\Microsoft\\""
TestExe -echoargs --% """%ProgramFiles(x86)%\Microsoft\\""

Catatan

Karakter garis miring terbalik (\) tidak dikenali sebagai karakter escape oleh PowerShell. Ini adalah karakter escape yang digunakan oleh API yang mendasari untuk ProcessStartInfo.ArgumentList.

PowerShell 7.3 juga menambahkan kemampuan untuk melacak pengikatan parameter untuk perintah asli. Untuk informasi selengkapnya, lihat Trace-Command.

Meneruskan argumen ke perintah PowerShell

Dimulai di PowerShell 3.0, Anda dapat menggunakan token akhir parameter (--) untuk menghentikan PowerShell menginterpretasikan input sebagai parameter PowerShell. Ini adalah konvensi yang ditentukan dalam spesifikasi POSIX Shell dan Utilitas.

Token akhir parameter

Token akhir parameter (--) menunjukkan bahwa semua argumen yang mengikutinya akan diteruskan dalam bentuk sebenarnya seolah-olah tanda kutip ganda ditempatkan di sekitarnya. Misalnya, menggunakan -- Anda dapat menghasilkan string -InputObject tanpa menggunakan tanda kutip atau membuatnya ditafsirkan sebagai parameter:

Write-Output -- -InputObject
-InputObject

Tidak seperti token stop-parsing (--%), nilai apa pun yang mengikuti -- token dapat ditafsirkan sebagai ekspresi oleh PowerShell.

Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64

Perilaku ini hanya berlaku untuk perintah PowerShell. Jika Anda menggunakan -- token saat memanggil perintah eksternal, string diteruskan sebagai argumen ke perintah tersebut -- .

TestExe -echoargs -a -b -- -c

Output menunjukkan bahwa -- diteruskan sebagai argumen ke TestExe.

Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>

Lihat juga