Modifier temporairement le répertoire de la commande de fichier batch unique

19

En shell-scripting, si j'ai besoin d'exécuter une commande à partir d'un répertoire, je peux nous un sous-shell pour m'assurer de revenir au contexte d'origine:

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

Cela peut-il être fait dans des fichiers batch Windows (ou des fichiers cmd)

Faire de même dans les fichiers batch me laisse dans le nouveau répertoire.

Je peux faire:

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

Mais le popd dépend du succès de command.

Des idées?

Greg
la source
Comment invoquez-vous votre "fichier batch" ou "fichier cmd"? Si vous placez une commande cd dans un script shell et exécutez ce script (pas le source), le répertoire de travail actuel du shell appelant ne changera pas.
garyjohn
Juste pour être clair, cela fait référence aux fichiers batch de Windows.
Greg
C'est un script qui exécute un tas de commandes dans différentes parties d'une arborescence de répertoires. Certaines commandes ne fonctionnent que sur le répertoire courant. Le retour au répertoire d'origine permet de simplifier les données qui pilotent le script. Suggérez-vous de créer un fichier de commandes distinct pour chaque répertoire dans lequel j'ai besoin d'appeler?
Greg
Si je me souviens bien, vous avez fait référence aux scripts shell et n'avez pas mentionné Windows dans votre question d'origine, donc j'ai supposé à tort que vous utilisiez un système de type Unix. Maintenant, je comprends.
garyjohn
Oui, désolé, je me rends compte que je n'étais pas clair (bien que je pense que 'batch-file' était un indice :-p)
Greg

Réponses:

21

Si tu fais:

pushd \windows && foobar && popd

vous serez laissé (comme vous le dites) dans le dossier \ windows. Essayer:

pushd \windows & foobar & popd

et vous devriez vous retrouver là où vous avez commencé.

BillP3rd
la source
1
Ah, donc l'esperluette simple est l'équivalent du point-virgule en sh. C'est parfait. (et une référence: ss64.com/nt/syntax-conditional.html )
Greg
6
Il est bon de se rappeler que cd/ pushdéchoue parfois (si le répertoire n'existe pas, par exemple). pushd \windows && (foobar & popd)peut être plus fiable
user1686
16

Par défaut, les fichiers de commandes Windows sont exécutés dans le contexte du shell parent (ce qui est inhabituel pour les utilisateurs Unix, où un explicite sourceest nécessaire, mais c'était la seule possibilité dans MS-DOS). Cela signifie que les changements de répertoire et les variables d'environnement affectent également le shell interactif d'origine.

Placez- setlocalle en haut de votre script pour le faire fonctionner dans son propre contexte - vous pouvez alors l'utiliser en toute sécurité cdà l'intérieur du script.

user1686
la source
Merci, cela ressemble à ce dont j'ai besoin - je le vérifierai lorsque j'aurai accès à une machine Windows. Cela affecterait-il les sous-commandes utilisant des parenthèses?
Greg
1
@Greg: Il semble que ( )seules les commandes de groupe, mais toujours les exécuter dans le contexte parent. (setlocal & cd foo & bar)ne fonctionnera pas; à la place pushd foo && (bar & popd)serait nécessaire.
user1686
4

Comme grawity mentionné précédemment, pushd \windows && (foobar & popd)fonctionnerait mieux que pushd \windows & foobar & popdparce que ce dernier peut échouer s'il n'y a pas un tel répertoire.

De plus, l'utilisation de setlocalet endlocalvous permet d'avoir plusieurs environnements locaux, par exemple, vous pourriez avoir:

setlocal

cd dir

command

endlocal

Vous serez maintenant de retour dans votre répertoire d'origine.

Timtech
la source
3

Vous pouvez utiliser cd -pour revenir au répertoire de travail précédent. Et utilisez ;plutôt que &&, les commandes suivantes ne dépendront pas du succès des commandes précédentes.

$ pwd
/etc
$ cd /var ; pwd ; cd -
/var
$ pwd
/etc
bahamat
la source
J'ai mis à jour la question pour préciser que je pose des questions sur les scripts batch / shell de Windows. Je sais comment le faire sous un shell en forme de sh :)
Greg
Comme l'a souligné BillP3rd, l'équivalent de ';' dans les fichiers batch est '&'.
Greg
Ah désolé. Votre utilisation des barres obliques m'a fait penser que c'était UNIX.
bahamat
1

J'applaudis la suggestion de grawity de mettre setlocalau début de votre script batch, mais j'ajouterais le fait que vous pouvez avoir plusieurs blocs setlocal/ imbriqués endlocal, donc une réponse plus pertinente à la question pourrait être

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

Et, bien sûr, si vous voulez que la commande soit exécutée uniquement si le cdto dir2réussit, disons .cddir2&&command

Notez que le bloc setlocal/ endlocalcrée un environnement localisé, donc toutes les variables que vous définissez ou modifiez dans un tel bloc reviendront à leur valeur précédente après le endlocal.

Scott
la source
0

Vous pouvez enregistrer le répertoire actuel dans une variable. Modifiez et modifiez en fonction de la valeur de retour de la commande. BTW,% CD% renvoie votre DIR actuel.

surfasb
la source