Obter o diretório atual do arquivo em lote

283

Primeiro, vi esse tópico, mas não consegui entender.

Pergunta:

Há um arquivo em lotes D:\path\to\file.batcom o seguinte conteúdo:

echo %cd%
pause

A saída é:

C:\

Deve ser D:\path\to

O que estou fazendo de errado?

Hamed Kamrava
fonte
7
Você deve ler todas as respostas a uma pergunta, especialmente as que obtêm mais votos, e não apenas a aceita. A resposta com a pontuação mais alta no link publicado já responde à sua pergunta.
dbenham
4
Se você estiver em c: \ ao digitar o nome do arquivo em lotes, c: \ será o que% cd% imprimirá.
foxidrive

Respostas:

496

A variável somente leitura do sistema %CD%mantém o caminho do chamador do lote, não o local do arquivo em lote.

Você pode obter o nome do script em lote, digitado pelo usuário com %0(por exemplo scripts\mybatch.bat). Extensões de parâmetros podem ser aplicadas a isso %~dp0, retornando o Drive e o Caminho para o script em lote (por exemplo W:\scripts\) e %~f0retornando o nome do caminho completo (por exemplo W:\scripts\mybatch.cmd).

Você pode consultar outros arquivos na mesma pasta que o script em lote usando esta sintaxe:

CALL %0\..\SecondBatch.cmd

Isso pode até ser usado em uma sub-rotina, Echo %0fornecerá o rótulo de chamada, mas echo "%~nx0"fornecerá o nome do arquivo do script em lote.

Quando a %0variável é expandida, o resultado é colocado entre aspas.

Mais sobre parâmetros de lote .

Stoleg
fonte
1
Olha, eu não preciso para ser executado stm.sqlno D:\Dir1\Dir2\stm.sql. Eu preciso mysql.exe -u root -p mysql < %cd%\stm.sqlexecutar os comandos stm.sql.
Hamed Kamrava
@HamedKamrava é para o meu lote SQL? arquivo em lote como *.batou *.sh?
Stoleg
@ Stoleg- De fato, existem 2 arquivos em D:\Dir1\Dir2\batchfile.bate D:\Dir1\Dir2\stm.sql. O conteúdo do batchfile.bat é: mysql.exe -u root -p mysql < D:\Dir1\Dir2\stm.sqle o conteúdo do stm.sql é alguns comandos do MySQL.
Hamed Kamrava
1
A variável somente leitura do sistema% CD% mantém o caminho do chamador do lote, não o local do arquivo em lote.
Stoleg
34
echo %~dp0retornará o caminho para o local do lote. echo %~f0retornará o caminho para o lote com o nome do arquivo.
Stoleg
119

Muito simples:

setlocal
cd /d %~dp0
File.exe
shay
fonte
9
O código é curto, mas não é simples de entender. O que é este File.exe? O caminho do diretório atual é armazenado em% ~ dp0?
Ivailo Bardarov 5/05
Esta resposta realmente responde à pergunta, eu acho. Parabéns.
macetw
3
Eu apenas usei cd /d %~dp0como primeira linha de arquivo de lote e trabalhou
mkb
por que precisa setlocal? retorna bem sem isso também?
T.Todua
1
@ T.Todua "setlocal" faz com que quaisquer alterações no ambiente, incluindo o diretório atual, sejam mantidas até o arquivo em lotes terminar ou um "endlocal" ser encontrado. Se você vai alterar variáveis ​​de ambiente ou o diretório atual, é uma boa forma.
25718 Jamie
30

Dentro do seu arquivo .bat:

set mypath=%cd%

Agora você pode usar a variável %mypath%para referenciar o caminho do .batarquivo. Para verificar se o caminho está correto:

@echo %mypath%

Por exemplo, um arquivo chamado DIR.batcom o seguinte conteúdo

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

executar a partir do diretório g:\test\batecoará esse caminho na janela de comando do DOS.

roqueiro
fonte
1
esta é a solução melhor e mais simples
Nani
7
Essa não é uma boa solução, pois não leva em consideração o script em lote que está sendo chamado de outro arquivo em outro caminho.
theQuestionMan
Além disso, quando executado como permissões elevadas, o% cd% retorna C: \ Windows \ system32, mas não o diretório em que está armazenado.
PravyNandas
9

Aqui está o que eu uso na parte superior de todos os meus arquivos em lotes. Acabei de copiar / colar da minha pasta de modelos.

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

Definir o caminho do arquivo em lotes atual para% batdir% permite chamá-lo em stmts subseqüentes no arquivo em lotes atual, independentemente de onde esse arquivo em lote é alterado. O uso do PUSHD permite que você use o POPD para definir rapidamente o caminho desse arquivo em lote como% batdir% original. Lembre-se, se você estiver usando% batdir% ExtraDir ou% batdir% \ ExtraDir (dependendo da versão usada acima, terminando a barra invertida ou não), será necessário colocar a cadeia inteira entre aspas duplas se o caminho tiver espaços (por exemplo, "% batdir% ExtraDir" ) Você sempre pode usar PUSHD% ~ dp0. [https: // ss64.com/ nt / syntax-args .html] possui mais parâmetros (% ~).

Observe que usar (: :) no início de uma linha faz com que seja uma linha de comentário. Mais importante, usar :: permite incluir redirecionadores, canais, caracteres especiais (por exemplo, <> | etc) nesse comentário.

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

Claro, o Powershell faz isso e muito mais.

Wendell Holmes
fonte
2
Ótima resposta, muito obrigado! :-) Apenas tome cuidado com sua segunda técnica ( set batdir=%CD%). Não está bom, porque é o caminho para o chamador, não o próprio arquivo bat. A única maneira válida de obter o caminho para o arquivo bat em execução é %~dp0.
Mitch McMabers