perché il mio cd% myVar% viene ignorato?

Salvare il mio percorso originale in originalPath e quindi passare a un’altra cartella. Alla fine, quando eseguo cd %originalPath% , non funziona. Rimane nel nuovo percorso.

Ho provato a usare pushd %myPath% e popd , ma non funziona neanche.

C:\BatchTests\ ha il mio script e la cartella Subfolder1 .

La mia sceneggiatura:

 @echo off set myPath=Subfolder1 set folderList=input.txt REM set originalPath=%CD% set originalPath=%~dp0 REM pushd %myPath% cd %myPath% setlocal EnableDelayedExpansion :process REM The rest of my script echo %originalPath% REM echo %originalPath% prints: C:\BatchTests\ cd %originalPath% REM popd pause 

Perché sta succedendo?

1. Citare percorsi sconosciuti

I percorsi non noti durante l’esecuzione di un file batch e non vengono corretti potrebbero contenere 1 o più spazi. Ciò significa che le stringhe di percorso dovrebbero essere citate come nomi di file.

2. Cambia unità e directory

Il CD di comando cambia per impostazione predefinita solo la directory corrente sull’unità corrente.

L’opzione /D per modificare la directory corrente in una directory su qualsiasi unità con una lettera deve essere sempre utilizzata quando la directory corrente all’avvio di un file batch non è fissa sulla stessa unità della directory corrente temporaneamente utilizzata.

3. setlocal e endlocal salvano e ripristinano anche la directory corrente

Il comando setlocal crea sempre una nuova copia della tabella dell’ambiente che viene distrutta quando si utilizza endlocal o si esce dal file batch ripristinando la tabella precedente. Inoltre, gli stati delle estensioni dei comandi e dell’espansione ritardata vengono salvati e ripristinati. Vedi questa risposta con un esempio che dimostra cosa succede usando setlocal e endlocal .

Ma anche setlocal salva anche la directory corrente e endlocal lo ripristina come dimostra il codice seguente.

 @echo off set "InitialPath=%CD%" echo 1. Current directory is: %CD% cd /D "%windir%\Temp" echo 2. Current directory is: %CD% setlocal rem Change current directory to parent directory. cd ..\ echo 3. Current directory is: %CD% setlocal rem Change current directory to root of current drive. cd \ echo 4. Current directory is: %CD% endlocal echo 5. Current directory is: %CD% endlocal echo 6. Current directory is: %CD% cd /D "%InitialPath%" echo 7. Current directory is: %CD% set "InitialPath=" pause 

4. Spazi finali e tab assegnati alla variabile di ambiente

Non utilizzando le virgolette doppie sull’assegnazione di un valore a una variabile di ambiente, il comando set aggiunge tutto dopo il primo segno di uguale alla fine della riga alla variabile di ambiente, compresi gli spazi finali e le tabulazioni non visibili. Ci sono spazi finali sul set originalPath=%~dp0 linee set originalPath=%~dp0 , vedi risposta su Perché non c’è output di stringa con ‘echo% var%’ dopo aver usato ‘set var = text’ sulla riga di comando? per ulteriori dettagli.


Il codice è stato migliorato per evitare tutti i possibili problemi sopra elencati:

 @echo off set "myPath=Subfolder1" set "folderList=input.txt" REM set "originalPath=%CD%" set "originalPath=%~dp0" REM pushd "%myPath%" cd /D "%myPath%" setlocal EnableDelayedExpansion :process REM The rest of my script endlocal echo %originalPath% REM echo %originalPath% prints: C:\BatchTests\ cd /D "%originalPath%" REM popd pause 

E prendendo in considerazione il punto 3 e come l’ aschipfl ha anche spiegato bene, anche il seguito potrebbe funzionare.

 @echo off set "myPath=Subfolder1" set "folderList=input.txt" setlocal EnableDelayedExpansion cd /D "%myPath%" :process REM The rest of my script endlocal pause 

In realtà non rimane nella directory modificata. Il vero problema è che setlocal , oltre alle modifiche alle variabili d’ambiente, memorizza nella cache la directory corrente, che è già stata modificata da cd %myPath% .

Quindi si ritorna alla directory precedente di cd %originalPath% . Ma non appena lo script batch termina l’esecuzione, si verifica un endlocal implicito che reimposta la directory corrente su quella precedentemente memorizzata da setlocal .

Il problema è esattamente lo stesso se si rimuovono REM dalle linee pushd e popd e si commentano invece le linee cd .

Per risolvere il problema, sposta semplicemente la cd %myPath% (o il comando pushd ) in basso sotto setlocal . In realtà non è nemmeno necessario memorizzare la directory corrente inizialmente quando la si cambia solo tra il blocco setlocal / endlocal (anche se endlocal non è esplicitamente indicato):

 @echo off set myPath=Subfolder1 set folderList=input.txt setlocal EnableDelayedExpansion REM pushd %myPath% cd %myPath% :process REM The rest of my script REM popd pause endlocal