Caracterele speciale în fișierul Batch (Programare, Windows, Fișier Batch, Cmd, Scăparea)

Matthew Rhoden a intrebat.

Caracterele speciale în fișierele batch sunt o pacoste, dar nu am găsit soluția potrivită pentru a scăpa în mod corespunzător primele două caractere din acest șir special pe care încerc să îl transmit aplicației.

SET pass=^&AntiBatchfileString
A_Program.exe /pass=%pass%

Lucrurile pe care le-am încercat:

:: Escaping the escape twice, first for ^, second for &.
SET pass=^^^^&AntiBatchfileString
echo %pass%

:: Combining escapes.
SET first=^^
SET second=^^&AntiBatchfileString
SET pass=%first%%second%
echo %pass%

:: Preventing expansion
SET first=^^
SET second=^^&AntiBatchfileString
SET pass=!first!%second%
echo %pass%

:: I got this to print correctly
SET "pass=^&AntiBatchfileString"
echo ^^%pass%

Tot atunci când trece ultimul nu acceptă autentificarea, nu știu care este rezultatul final. Asta m-a făcut să mă gândesc că poate încearcă să facă o altă expansiune atunci când pasează parametrul către aplicație, așa că am citat și asta.

SET "pass=^&AntiBatchfileString"
A_Program.exe "/pass=^^%pass%"

Tot nu funcționează, nu știu ce îmi scapă în acest moment.

Comentarii

  • Posibil duplicat al scăpării caracterelor din lot –  > Por phuclv.
1 răspunsuri
aschipfl

Să presupunem că doriți ca șirul ^&AntiBatchfileString literal, aceasta este cea mai bună soluție set sintaxă, deoarece majoritatea caracterelor speciale (^ & ( ) < > | și, de asemenea, delimitatorii standard , ; = SPACE TAB) își pierd semnificația specială imediat ce sunt plasate între "", și "" nu devin ele însele parte a valorii variabilei:

set "pass=^&AntiBatchfileString"

Acest lucru funcționează numai atâta timp cât extensiile de comandă sunt activate, ceea ce oricum este implicit în Windows (tastați cmd /? și veți vedea /E opțiunea).

Atunci când se extinde (se citește) o variabilă de tipul "%pass%" (cu învelișul ""), caracterele speciale sunt în continuare tratate literal.

Cu toate acestea, de îndată ce o extindeți ca %pass% (fără ""), acestea își recapătă semnificația specială. Astfel, aveți următoarele opțiuni:

  1. Utilizați set "pass=^^^&AntiBatchfileString", , unde ^^ evadează literalul ^ și ^& literalul & atunci când se citește ca %pass%.
  2. Activați expansiunea întârziată (a se vedea set /? despre cum funcționează și setlocal /? sau cmd /? despre cum să o activați), în care valoarea variabilei este extinsă (citită) într-un moment în care analizarea caracterelor speciale a fost deja finalizată.

Prefer această din urmă abordare, deoarece nu este necesară o scăpare specială și poate face față și la " care apar în valoarea șirului de caractere (chiar dacă sunt prezente în mod nesimetric).
Apropo, " poate fi, de asemenea, scăpat prin ^", , atâta timp cât acesta nu apare în cadrul unui text neeșapat "".

Cu toate acestea, % nu pot fi scăpate ca ^% într-un fișier batch, deoarece expansiunea procentuală are loc înainte de scăpare, ci trebuie să le dublați ca %% pentru a obține câte unul literal, indiferent dacă șirul se află sau nu între "".
Rețineți că pe consolă, %% nu funcționează.

În cele din urmă, literal ! sunt consumate de caracteristica de expansiune întârziată atunci când este activată, prin urmare trebuie să acordați o atenție deosebită acestora în cazul în care, prin scăparea lor ca ^!, , sau, de asemenea, prin comutarea inteligentă a expansiunii întârziate (prin urmare, pentru a o activa doar atunci când este într-adevăr necesară și pentru a o dezactiva în caz contrar, atunci când este furnizat un șir literal, ca într-un fișier set linie de comandă, de exemplu, atunci când se extinde o variabilă standard precum %pass% și atunci când se citește un for variabilă de tipul %%I (fișier batch) sau %I (consolă), de exemplu). Bineînțeles că nici aceasta nu este soluția finală, deoarece aveți nevoie de setlocal și endlocal pentru a activa/dezactiva expansiunea întârziată, care au rolul de a localiza modificările de mediu, astfel încât orice modificare de variabilă de la cea mai recentă setlocal comandă sunt pierdute imediat ce endlocal este executată (există câteva trucuri pentru a trece o valoare de variabilă peste endlocal barieră totuși).

Comentarii

  • Ah, înțeleg acum, plus că după ce m-am jucat atât de mult cu ea nu mi-am dat seama că am lăsat această parte în "/pass=%pass%" în timp ce încercam celelalte lucruri. Acum funcționează și mulțumesc pentru sfaturi, @aschipfl! –  > Por Matthew Rhoden.