Kutipan melarikan diri dan tanda kutip ganda

94

Bagaimana cara saya melepaskan tanda kutip pada -paramnilai di baris perintah berikut dengan benar?

$cmd="\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'""
Invoke-Expression $cmd 

Ini tentu saja gagal. Saya mencoba untuk melepaskan diri dari tanda kutip (tunggal dan ganda) menggunakan karakter escape` dan melakukan berbagai kombinasi, tetapi tidak ada yang berhasil.

eetawil
sumber
Lihat juga Invoke-Expression dianggap berbahaya .
Peter Mortensen
@PeterMortensen ada masalah dengan artikel ini, adalah bahwa tampaknya tidak ada cara yang lebih baik, ketika Anda ingin meluncurkan aplikasi asli dan meneruskan parameter yang menyertakan kutipan ganda sebagai argumen
Andrew Savinykh
@ Andrew Savinykh: Salah satu cara adalah untuk memulai itu melalui cmd gantinya: $someCommandStringWithDoubleQuotes | cmd. Ini sebenarnya bekerja dari skrip PowerShell (misalnya menjalankan CMake (yang memang memerlukan tanda kutip ganda (jika tidak maka akan gagal secara diam-diam))). Alternatif untuk CMD adalah bash.exe ( MinGW ) - tetapi mungkin sangat, sangat lambat untuk memulai dalam beberapa keadaan.
Peter Mortensen

Jawaban:

60

Parameter pelarian seperti itu biasanya menjadi sumber frustrasi dan terasa seperti waktu yang terbuang percuma. Saya melihat Anda menggunakan v2, jadi saya sarankan untuk menggunakan teknik yang dibuat oleh Joel "Jaykul" Bennet di blog beberapa waktu yang lalu .

Singkat cerita: Anda cukup membungkus string Anda dengan @ '...' @:

Start-Process \\server\toto.exe @'
-batch=B -param="sort1;parmtxt='Security ID=1234'"
'@

(Ingatlah bahwa saya mengasumsikan kutipan mana yang diperlukan, dan hal-hal yang Anda coba hindari.) Jika Anda ingin bekerja dengan output, Anda mungkin ingin menambahkan -NoNewWindowsakelar.

BTW: ini adalah masalah yang sangat penting sehingga sejak v3 Anda dapat menggunakan --%untuk menghentikan pengurai PowerShell melakukan apa pun dengan parameter Anda:

\\server\toto.exe --% -batch=b -param="sort1;paramtxt='Security ID=1234'"

... harus bekerja dengan baik di sana (dengan asumsi yang sama).

BartekB
sumber
Terima kasih atas jawaban Anda. mulai-proses bagaimanapun saya berusaha selalu mengeluh. JADI saya melakukan cmd / C $ cmd (di mana $ cmd adalah seluruh perintah saya termasuk .exe.). Saya menggunakan PowerShell 2.0. Bahkan string di sini tidak berfungsi jika saya ingat dengan benar.
eetawil
3
Ini tampaknya tidak perlu rumit dibandingkan menggunakan backtick (`) untuk menghindari tanda kutip ganda.
saille
6
Ini bekerja dengan baik selama Anda mengikuti aturan yang diharapkan. @ 'Pertama harus ada di "baris 1", parameter Anda harus di "baris 2" dan akhiran' @ harus di "baris 3". Akhiran '@ tidak boleh diberi spasi sebelumnya. Man, sintaks ini pilih-pilih!
Ian Newland
Bekerja dengan baik! Jika Anda perlu memperluas variabel dalam string Anda, Anda dapat menggunakan @"dan "@sebagai gantinya.
alis
97

Menggunakan backtick (`) berfungsi dengan baik untuk saya jika saya meletakkannya di tempat-tempat berikut:

$cmd="\\server\toto.exe -batch=B -param=`"sort1;parmtxt='Security ID=1234'`""

$cmd kembali sebagai:

\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'"

Itukah yang kamu cari?

Kesalahan yang diberikan PowerShell kepada saya mengacu pada token tak terduga 'sort1', dan begitulah cara saya menentukan di mana harus meletakkan backticks.

Sintaks @ '...' @ disebut "string di sini" dan akan mengembalikan apa yang dimasukkan. Anda juga dapat menggunakannya untuk mengisi variabel dengan cara berikut:

$cmd=@'
"\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'""
'@

Simbol pembuka dan penutup harus berada pada barisnya masing-masing seperti gambar di atas.

Owen B
sumber
Maaf atas keterlambatannya ... cara saya membuatnya bekerja adalah akhirnya memanggil cmd / C "MYCOMMAND" dari PowerShell. Itu tidak berhasil menggunakan PowerShell secara langsung.
eetawil
1
Tapi tidakkah Invoke-Expressionmenghapus tanda kutip ganda dari $cmdsaat dipanggil? Atau bagaimana Anda menggunakan $cmdtanpa menggunakan Invoke-Expression?
Peter Mortensen
8

Saya menemukan diri saya dalam kesulitan yang sama hari ini ketika mencoba menjalankan perintah melalui modul Node.js:

Saya menggunakan PowerShell dan mencoba menjalankan:

command -e 'func($a)'

Tetapi dengan simbol tambahan, PowerShell mengacaukan argumen. Untuk memperbaikinya, saya mencentang ulang tanda kutip ganda yang lolos:

command -e `"func($a)`"
pranspach
sumber
2
menarik: "['`"][^'`"]['`"]"berhasil… tetapi '[`'"][^`'"][`'"]'tidak! membuatku gila
David J