Obtenir le répertoire du fichier batch actuel

283

Premièrement, j'ai vu ce sujet mais je ne pouvais pas comprendre cela.

Question:

Il y a un fichier batch D:\path\to\file.batavec le contenu suivant:

echo %cd%
pause

La sortie est:

C:\

Ce doit être D:\path\to

Qu'est-ce que je fais mal?

Hamed Kamrava
la source
7
Vous devriez lire toutes les réponses à une question, en particulier les personnes qui obtiennent le plus de voix, et pas seulement celle acceptée. La réponse avec le score le plus élevé sur votre lien affiché répond déjà à votre question.
dbenham
4
Si vous êtes dans c: \ lorsque vous tapez le nom du fichier de commandes, c: \ est ce que% cd% imprimera.
foxidrive

Réponses:

497

La variable en lecture seule du système %CD%conserve le chemin de l'appelant du lot, pas l'emplacement du fichier de lot.

Vous pouvez obtenir le nom du script batch lui-même tel que tapé par l'utilisateur avec %0(par exemple scripts\mybatch.bat). Des extensions de paramètres peuvent être appliquées à cela, donc %~dp0retourneront le lecteur et le chemin d'accès au script batch (par exemple W:\scripts\) et %~f0renverront le chemin complet (par exemple W:\scripts\mybatch.cmd).

Vous pouvez faire référence à d'autres fichiers dans le même dossier que le script batch en utilisant cette syntaxe:

CALL %0\..\SecondBatch.cmd

Cela peut même être utilisé dans un sous-programme, Echo %0 donnera l'étiquette d'appel mais, echo "%~nx0"vous donnera le nom de fichier du script batch.

Quand le %0 variable est développée, le résultat est placé entre guillemets.

Plus d'informations sur les paramètres de lot .

Stoleg
la source
1
Regardez, je ne pas besoin de courir stm.sqldans D:\Dir1\Dir2\stm.sql. J'ai besoin mysql.exe -u root -p mysql < %cd%\stm.sqld'exécuter ces commandes stm.sql.
Hamed Kamrava
@HamedKamrava est-ce pour mon lot SQL? pas de fichier batch comme *.batou *.sh?
Stoleg
@ Stoleg- En fait, il y a 2 fichiers dans D:\Dir1\Dir2\batchfile.batet D:\Dir1\Dir2\stm.sql. le contenu de batchfile.bat est: mysql.exe -u root -p mysql < D:\Dir1\Dir2\stm.sqlet le contenu stm.sql est quelques commandes MySQL.
Hamed Kamrava
1
La variable système en lecture seule% CD% conserve le chemin de l'appelant du lot, pas l'emplacement du fichier de lot.
Stoleg
35
echo %~dp0retournera le chemin vers l'emplacement du lot. echo %~f0renverra le chemin vers le lot avec le nom de fichier.
Stoleg
119

Très simple:

setlocal
cd /d %~dp0
File.exe
shay
la source
9
Le code est court mais il n'est pas simple à comprendre. Qu'est-ce que ce fichier.exe? Le chemin du répertoire actuel est-il stocké dans% ~ dp0?
Ivailo Bardarov
Cette réponse répond en fait à la question, je pense. Gloire.
macetw
3
Je viens d'utiliser cd /d %~dp0la première ligne du fichier de commandes et
j'ai
pourquoi avoir besoin de setlocal? ça revient bien sans ça aussi?
T.Todua
1
@ T.Todua "setlocal" provoque toute modification de l'environnement, y compris le répertoire actuel, jusqu'à ce que le fichier de commandes se termine ou qu'un "endlocal" soit rencontré. Si vous allez changer des variables d'environnement ou le répertoire courant, c'est une bonne forme.
Jamie
30

Dans votre fichier .bat:

set mypath=%cd%

Vous pouvez maintenant utiliser la variable %mypath%pour référencer le chemin d'accès au .batfichier. Pour vérifier que le chemin est correct:

@echo %mypath%

Par exemple, un fichier appelé DIR.batavec le contenu suivant

set mypath=%cd%
@echo %mypath%
Pause

exécuté à partir du répertoire g:\test\batfera écho à ce chemin dans la fenêtre de commande DOS.

rockerron
la source
1
c'est la solution la plus fine et la plus simple
Nani
7
Ce n'est pas une bonne solution car elle ne prend pas en compte le script batch appelé depuis un autre fichier sur un autre chemin.
theQuestionMan
également lorsqu'il est exécuté avec des autorisations élevées,% cd% renvoie C: \ Windows \ system32 mais pas le répertoire où il est stocké.
PravyNandas
9

Voici ce que j'utilise en haut de tous mes fichiers batch. Je viens de copier / coller à partir de mon dossier de modèles.

@echo off
:: --HAS ENDING BACKSLASH
set batdir=%~dp0
:: --MISSING ENDING BACKSLASH
:: set batdir=%CD%
pushd "%batdir%"

La définition du chemin du fichier de commandes en cours sur% batdir% vous permet de l'appeler dans les commandes suivantes du fichier de commandes en cours, quel que soit l'endroit où ce fichier de commandes passe. L'utilisation de PUSHD vous permet d'utiliser POPD pour définir rapidement le chemin d'accès de ce fichier de commandes à% batdir% d'origine. N'oubliez pas que si vous utilisez% batdir% ExtraDir ou% batdir% \ ExtraDir (selon la version utilisée ci-dessus, en mettant fin ou non à la barre oblique inverse), vous devrez mettre la chaîne entière entre guillemets si le chemin a des espaces (c'est-à-dire "% batdir% ExtraDir" ). Vous pouvez toujours utiliser PUSHD% ~ dp0. [https: // ss64.com/ nt / syntax-args .html] contient plus de paramètres (% ~).

Notez que l'utilisation de (: :) au début d'une ligne en fait une ligne de commentaire. Plus important encore, l'utilisation de :: vous permet d'inclure des redirecteurs, des canaux, des caractères spéciaux (c'est-à-dire <> | etc) dans ce commentaire.

:: ORIG STMT WAS: dir *.* | find /v "1917" > outfile.txt

Bien sûr, Powershell fait cela et bien plus encore.

Wendell Holmes
la source
2
Excellente réponse, merci beaucoup! :-) Attention à votre deuxième technique ( set batdir=%CD%). Ce n'est pas correct, car c'est le chemin d'accès à l'appelant, pas le fichier bat lui-même. La seule façon valide d'obtenir le chemin d'accès au fichier bat en cours d'exécution est %~dp0.
Mitch McMabers