Gestire le citazioni negli script batch di Windows

In un file batch di Windows, quando si effettua quanto segue:

set myvar="c:\my music & videos"

la variabile myvar è memorizzata con le virgolette incluse. Sinceramente lo trovo molto stupido. Le virgolette servono solo per dire dove inizia e finisce la stringa, non per essere memorizzate come parte del valore stesso.
Come posso evitare che ciò accada?

Grazie.

 set "myvar=c:\my music & videos" 

Si noti che le virgolette iniziano prima di myvar. In realtà è così semplice. Nota a margine: myvar non può essere ripetuto in seguito a meno che non sia racchiuso tra virgolette perché verrà letto come separatore di comandi, ma funzionerà comunque come un percorso.

http://ss64.com/nt/set.html in “I nomi delle variabili possono includere spazi”

Questo è il modo corretto per farlo:

 set "myvar=c:\my music & videos" 

Le virgolette non saranno incluse nel valore della variabile.

Dipende da come si desidera utilizzare la variabile. Se si desidera utilizzare il valore della variabile senza le virgolette, è ansible utilizzare l’espansione ritardata e la sostituzione di stringhe o il comando for :

 @echo OFF SETLOCAL enabledelayedexpansion set myvar="C:\my music & videos" 

Come afferma andynormancx, le virgolette sono necessarie poiché la stringa contiene & . Oppure puoi sfuggirlo con il ^ , ma penso che le virgolette siano un po ‘più pulite.

Se si utilizza l’espansione ritardata con sostituzione di stringhe, si ottiene il valore della variabile senza le virgolette:

 @echo !myvar:"=! >>> C:\my music & videos 

Puoi anche usare il comando for :

 for /f "tokens=* delims=" %%P in (%myvar%) do ( @echo %%P ) >>> C:\my music & videos 

Tuttavia, se si desidera utilizzare la variabile in un comando, è necessario utilizzare il valore quotato o racchiudere il valore della variabile tra virgolette:

  1. Utilizzo della sostituzione di stringhe e dell’espansione ritardata per utilizzare il valore della variabile senza virgolette, ma utilizzare la variabile in un comando:

     @echo OFF SETLOCAL enabledelayedexpansion set myvar="C:\my music & videos" md %myvar% @echo !myvar:"=! created. 
  2. Usando il comando for per usare il valore della variabile senza virgolette, devi circondare la variabile con virgolette quando la usi nei comandi:

     @echo OFF set myvar="C:\my music & videos" for /f "tokens=* delims=" %%P in (%myvar%) do ( md "%%P" @echo %%P created. ) 

Per farla breve, non c’è davvero un modo pulito per utilizzare un percorso o un nome file che contiene spazi e / o & s incorporati in un file batch.

Usa jscript.

Molte lune fa (vale a dire circa 8 anni di give or take) stavo lavorando su un grande progetto C ++ / VB6, e avevo vari bit di Batch Script per fare parti della build.

Poi qualcuno mi ha indicato al test di Joel , ero particolarmente innamorato del punto 2 e ho iniziato a portare tutti i miei piccoli script di compilazione in un unico script di compilazione. . .

e mi ha quasi spezzato il cuore, facendo lavorare tutti quei piccoli script, su macchine diverse, con configurazioni leggermente diverse, voi Gods era terribile – in particolare impostando le variabili e il passaggio dei parametri. Era davvero fragile, la minima cosa avrebbe potuto romperlo e richiedere 30 minuti di tweaking per andare avanti di nuovo.

Alla fine – posso essere testardo di me – ho buttato tutto e in circa un giorno ho riscritto tutto in JavaScript , eseguendolo dal prompt dei comandi con CScript.

Non ho guardato indietro. Anche se in questi giorni è MSBuild e Cruise Control, se devo fare qualcosa anche leggermente coinvolto con uno script batch, io uso jscript.

L’interprete dei comandi di Windows consente di utilizzare le virgolette sull’intero comando set (valido in ogni versione di Windows NT da NT 4.0 a Windows 2012 R2)

Il tuo script dovrebbe essere scritto come segue:

 @echo OFF set "myvar=C:\my music & videos" 

Quindi puoi mettere le virgolette attorno alle variabili secondo necessità.

Lavorare con il prompt di CMD può sembrare esoterico, a volte, ma l’interprete di comandi si comporta in modo abbastanza solido nell’osservare la sua logica interna, è solo bisogno di ripensare le cose.

In effetti, il comando set non richiede affatto di usare virgolette, ma sia il modo in cui si sta facendo l’assegnazione della variabile sia il modo in cui il metodo di non usare virgolette può causare spazi extra attorno alla variabile che sono difficili da avviso durante il debug del tuo script.

Ad esempio entrambi i seguenti sono tecnicamente validi, ma puoi avere degli spazi finali, quindi non è una buona pratica:

 set myvar=some text set myvar="some text" 

Ad esempio, entrambi i seguenti sono buoni metodi per impostare le variabili nell’interprete di Comando di Windows, tuttavia il metodo di virgolette doppie è superiore:

 set "myvar=Some text" (set myvar=Some value) 

Entrambi non lasciano nulla all’interpretazione, la variabile avrà esattamente i dati che stai cercando.

testo forte Tuttavia, per i tuoi scopi, solo il metodo quotato funzionerà correttamente perché stai utilizzando un carattere riservato

Quindi, useresti:

 set myvar="c:\my music & videos" 

Tuttavia, anche se la variabile IS è correttamente impostata su questa stringa, quando ECHO lo sting l’interprete dei comandi interpreterà la e commerciale come la parola chiave per indicare che segue un’altra istruzione.

SO se vuoi echo la stringa dalla variabile, l’interprete CMD deve ancora essere detto che è una stringa di testo, o se non vuoi che le virgolette mostrino che devi fare una delle seguenti azioni:

echo la variabile con le citazioni:

 Echo."%myvar%" 

echo la variabile SENZA Citazioni:

 Echo.%myvar:&=^&%  

Nei due scenari precedenti puoi echo la stringa senza virgolette. Esempio di output di seguito:

 C:\Admin> Echo.%myvar:&=^&% C:\my music & videos C:\Admin>  

Devi avere le virgolette se il testo che stai impostando include determinati caratteri, incluso & . Se il tuo testo non includesse e quindi non avresti bisogno delle virgolette.

Ad esempio se il testo fosse solo “c: \ my music” allora potresti fare:

 set myvar = c:\my music 

Ma poiché il tuo testo ha un & hai bisogno delle virgolette.

Modificare:

O come dice Dave nella sua risposta, puoi sfuggire al problema con i caratteri ^^^ , ma attenti a questo approccio e non è l’unico personaggio che devi sfuggire. In pratica è molto più facile attenersi alle virgolette piuttosto che sfuggire a tutti i personaggi problematici.

Prova a usare il carattere di escape ‘^’, ad es

 set myvar=c:\my music ^& videos 

Dovrai fare attenzione quando espandi myvar perché la shell potrebbe non trattare il & & letteral. Se quanto sopra non funziona, prova ad inserire un segno di omissione nella stringa:

 set myvar=c:\my music ^^^& videos