Modifica temporanea della directory per il comando di un singolo file batch


19

In shell-scripting se ho bisogno di eseguire un comando da una directory posso farci una subshell per assicurarmi di tornare al contesto originale:

(cd temporary/new/directory ; command)
# now I am still in original directory

Questo può essere fatto in file batch di Windows (o file cmd)

Fare lo stesso nei file batch mi lascia nella nuova directory.

Posso fare:

pushd temporary\new\directory && command && popd

Ma il popd dipende dal successo di command.

Qualche idea?


Come stai invocando il tuo "file batch" o "file cmd"? Se si inserisce un comando cd in uno script di shell ed si esegue quello script (non lo si genera), l'attuale directory di lavoro della shell chiamante non cambierà.
garyjohn,

Giusto per essere chiari, questo si riferisce ai file batch di Windows.
Greg,

È uno script che esegue un gruppo di comandi in diverse parti di un albero di directory. Alcuni dei comandi funzionano solo nella directory corrente. Il ritorno alla directory originale aiuta a semplificare i dati che guidano lo script. Stai suggerendo di creare un file batch separato per ogni directory in cui devo effettuare chiamate?
Greg,

Come ricordo, hai fatto riferimento a script di shell e non hai menzionato Windows nella tua domanda originale, quindi ho erroneamente supposto che stavi usando un sistema simile a Unix. Ora capisco.
garyjohn,

Sì, scusa, mi rendo conto di non essere stato chiaro (anche se penso che 'batch-file' sia stato un suggerimento :-p)
Greg

Risposte:


21

Se fate:

pushd \windows && foobar && popd

rimarrai (come dici) nella cartella \ windows. Provare:

pushd \windows & foobar & popd

e dovresti ritrovarti da dove hai iniziato.


1
Ah, quindi la singola e commerciale è l'equivalente del punto e virgola in sh. È perfetto. (e un riferimento: ss64.com/nt/syntax-conditional.html )
Greg

6
È bene ricordare che cd/ a pushdvolte fallisce (se la directory non esiste, per esempio). pushd \windows && (foobar & popd)potrebbe essere più affidabile
user1686

16

Per impostazione predefinita, i file batch di Windows vengono eseguiti nel contesto della shell padre (cosa insolita per gli utenti Unix, dove sourceè necessario un esplicito , ma era l'unica possibilità in MS-DOS). Ciò significa che anche le modifiche alla directory e le variabili di ambiente influiscono sulla shell interattiva originale.

Mettilo setlocalnella parte superiore dello script per farlo funzionare nel suo contesto: puoi tranquillamente utilizzarlo cdall'interno dello script.


Grazie, suona come quello di cui ho bisogno: lo controllerò quando avrò accesso a un computer Windows. Ciò influirebbe sui sottocomandi usando le parentesi?
Greg,

1
@Greg: sembra che ( )solo i comandi di gruppo insieme, ma li eseguano ancora nel contesto padre. (setlocal & cd foo & bar)non funzionerà; invece pushd foo && (bar & popd)sarebbe necessario.
user1686

4

Come la gravità precedentemente menzionata, pushd \windows && (foobar & popd)funzionerebbe meglio che pushd \windows & foobar & popdperché quest'ultima potrebbe fallire se non esiste tale directory.

Inoltre, usando setlocale endlocalti permette di avere più ambienti locali, quindi ad esempio potresti avere:

setlocal

cd dir

command

endlocal

Ora torneresti nella tua directory originale.


3

È possibile utilizzare cd -per tornare alla directory di lavoro precedente. E usa ;invece di &&, quindi i comandi successivi non dipenderanno dal successo dei comandi precedenti.

$ pwd
/etc
$ cd /var ; pwd ; cd -
/var
$ pwd
/etc

Ho aggiornato la domanda per chiarire che sto chiedendo degli script batch / shell di Windows. So come farlo sotto una shell sh-like :)
Greg

Come BillP3rd ha sottolineato l'equivalente di ';' nei file batch è '&'.
Greg,

Mi dispiace. Il tuo uso di barre rovesciate mi ha fatto pensare che fosse UNIX.
Bahamat,

1

Mi congratulo con il suggerimento di Grawity di mettere setlocalall'inizio del tuo script batch, ma aggiungerei il fatto che puoi avere più, nidificati setlocal/ endlocalblocchi, quindi una risposta più pertinente alla domanda potrebbe essere

@echo off
setlocal
cddir1
  ...
setlocal
cddir2
command
endlocal
:: Now I am back indir1
  ...

E, naturalmente, se si desidera eseguire il comando solo se il cdto ha dir2esito positivo, dire .cddir2&&command

Si noti che il blocco setlocal/ endlocalcrea un ambiente localizzato, quindi tutte le variabili impostate o modificate in tale blocco torneranno al valore precedente dopo il endlocal.


0

È possibile salvare la directory corrente in una variabile. Cambia e cambia indietro a seconda del valore restituito dal comando. A proposito,% CD% restituisce il tuo DIR corrente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.