O que significa% ~ dp0 e como funciona?

1024

Acho %~dp0muito útil e o uso muito para tornar meus arquivos em lote mais portáteis.

Mas o rótulo em si parece muito enigmático para mim ... O que está ~fazendo? Faz dpmovimentação média e caminho? Refere- 0se ao %0caminho para o arquivo em lotes que inclui o nome do arquivo?

Ou é apenas um rótulo estranho?

Também gostaria de saber se é um recurso documentado ou se é algo que pode ser preterido.

Sebastián Grignoli
fonte
2
Você está certo, Hellen. Essa pergunta não apareceu quando procurei% ~ dp0. Talvez porque tenha% ~ d0 no título em vez de% ~ dp0.
Sebastián Grignoli 25/02
9
O SymbolHound é ótimo para realizar pesquisas que não sejam caracteres alfanuméricos. Por exemplo, procure%~dp0 . Normalmente, acho que os principais hits referem-se ao conteúdo do SO.
21815 DavidRR
O SymbolHound não funcionou para mim com a pesquisa symbolhound.com/?q=%25~dp0 . No entanto isso funcionou: google.com/search?q=%25~dp0 - só estou dizendo ...
Kristopher
1
SymbolHound 2019: Não funciona e o uMatrix indica que ele se conecta a sites de terceiros como blockchain.info e paypalobjects.com.
Nils Lindemann

Respostas:

811

Chamando

for /?

na linha de comando, fornece ajuda sobre essa sintaxe (que também pode ser usada fora do FOR, este é apenas o lugar onde a ajuda pode ser encontrada).

Além disso, a substituição das referências de variáveis ​​FOR foi aprimorada. Agora você pode usar a seguinte sintaxe opcional:

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file
%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string

Os modificadores podem ser combinados para obter resultados compostos:

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only
%~dp$PATH:I - searches the directories listed in the PATH
               environment variable for %I and expands to the
               drive letter and path of the first one found.
%~ftzaI     - expands %I to a DIR like output line

Nos exemplos acima,% I e PATH podem ser substituídos por outros valores válidos. A sintaxe% ~ é finalizada por um nome de variável FOR válido. Escolher nomes de variáveis ​​em maiúsculas como% I torna mais legível e evita confusão com os modificadores, que não diferenciam maiúsculas de minúsculas.

Existem letras diferentes que você pode usar como f"nome completo do caminho", dletra da unidade, pcaminho e elas podem ser combinadas. %~é o começo de cada uma dessas seqüências e um número Iindica que ele funciona no parâmetro %I(onde %0está o nome completo do arquivo em lotes, exatamente como você imaginou).

schnaader
fonte
2
Não conheço mais ninguém, mas recebo "O uso a seguir do operador path na substituição de parâmetros em lote é inválido. Para formatos válidos, digite CALL /? Ou FOR / ?. A sintaxe do comando está incorreta." ao usar I. Eu tenho que usar em 0vez de I. Não sei se perdi algo ou o que quer, mas apenas avise as pessoas.
Mythofechelon
71
@BenHooper, Ié um espaço reservado para o índice variável. 0= O arquivo de chamada, 1= argumento nº 1, 2= argumento # 2, etc ...
Chris
9
Essa resposta é boa. E exaustivo. Para um pouco mais brevidade, como a resposta a esta quase duplicado-pergunta: stackoverflow.com/questions/112055/...
Frank Nocke
1
Esta resposta é um pouco confusa porque essas substituições podem ser usadas fora do FOR.
David David
348

(Primeiro, eu gostaria de recomendar este site de referência útil para o lote: http://ss64.com/nt/ )

Depois, apenas mais uma explicação útil: http://htipe.wordpress.com/2008/10/09/the-dp0-variable/

A variável% ~ dp0

O% ~ DP0 (que é um zero) variável quando referenciados dentro de um arquivo de lote do Windows irá se expandir para o d carta rive e p ath desse arquivo em lotes.

As variáveis% 0-% 9 referem-se aos parâmetros de linha de comando do arquivo em lotes. % 1-% 9 referem-se aos argumentos da linha de comando após o nome do arquivo em lote. % 0 refere-se ao próprio arquivo em lotes.

Se você seguir o caractere de porcentagem (%) com um caractere til (~), poderá inserir um (s) modificador (es) antes do número do parâmetro para alterar a maneira como a variável é expandida. O modificador d se expande para a letra da unidade ep modificador para o caminho do parâmetro.

Exemplo: Digamos que você tenha um diretório em C: chamado bat_files, e nesse diretório esteja um arquivo chamado example.bat. Nesse caso,% ~ dp0 (combinando os modificadores de ep) será expandido para C: \ bat_files.

Confira este artigo da Microsoft para obter uma explicação completa.

Além disso, confira este tópico do fórum .

E uma referência mais clara daqui :

  • %CmdCmdLine% retornará toda a linha de comando conforme passada para o CMD.EXE

  • %* retornará o restante da linha de comando iniciando no primeiro argumento da linha de comando (no Windows NT 4,% * também inclui todos os espaços iniciais)

  • %~dn retornará a letra da unidade de% n (n pode variar de 0 a 9) se% n for um caminho ou nome de arquivo válido (sem UNC)

  • %~pn retornará o diretório de% n se% n for um caminho ou nome de arquivo válido (sem UNC)

  • %~nn retornará o nome do arquivo apenas% n se% n for um nome de arquivo válido

  • %~xn retornará a extensão do arquivo apenas% n se% n for um nome de arquivo válido

  • %~fn retornará o caminho completo de% n se% n for um nome ou diretório de arquivo válido

ADICIONAR 1

Acabei de encontrar uma boa referência para o misterioso ~ operador de til.

A %~string é chamada de operador percentual de til . Você pode encontrá-lo em situações como: %~0.

A :~string é chamada de operador de dois pontos . Você pode achar isso %SOME_VAR:~0,-1%.

ADICIONAR 2 - 13:12 06/06/2018

%1-%9consulte os argumentos da linha de comandos. Se eles não forem valores de caminho válidos, %~dp1+ %~dp9serão expandidos para o mesmo valor que %~dp0. Mas se forem valores de caminho válidos, eles serão expandidos para seu próprio valor de driver / caminho.

Por exemplo: (batch.bat)

@echo off
@echo ~dp0= %~dp0
@echo ~dp1= %~dp1
@echo ~dp2= %~dp2
@echo on

Execução 1:

D:\Workbench>batch arg1 arg2

~dp0= D:\Workbench\
~dp1= D:\Workbench\
~dp2= D:\Workbench\

Execução 2:

D:\Workbench>batch c:\123\a.exe e:\abc\b.exe

~dp0= D:\Workbench\
~dp1= c:\123\
~dp2= e:\abc\
smwikipedia
fonte
Também curioso sobre esse conceito e encontrei os bons esclarecimentos aqui. Obrigado Mingge. ^ _ ^
Eugene
1
para mim ele se expande para c: \ bat_files \ (com finais seperator path)
Santa
Os links para o artigo da Microsoft e o tópico do fórum não funcionam mais :(
wovano 26/05/19
151

A variável %0em um script em lote é definida como o nome do arquivo em lotes em execução.

A ~dpsintaxe especial entre o %e o 0basicamente diz para expandir a variável %0para mostrar a letra e o caminho da unidade, que fornece o diretório atual que contém o arquivo em lotes!

Help = Link

Andy White
fonte
@ Andy, existe alguma maneira de testar %0diretamente no cmd sem salvar um arquivo. Bat no disco rígido local?
Pacerier
O link está quebrado e não consigo encontrar o link correto. Uma edição pendente ainda tem o link quebrado.
George_E 24/01
44

% ~ dp0 expande para o caminho do diretório atual do arquivo em lotes em execução.

Para obter um entendimento claro, vamos criar um arquivo em lotes em um diretório.

C: \ script \ test.bat

com conteúdo:

@echo off
echo %~dp0

Ao executá-lo no prompt de comando, você verá este resultado:

C: \ script \

nulo
fonte
41

Outra dica que ajudaria muito é que, para definir o diretório atual para uma unidade diferente, seria necessário %~d0primeiro cd %~dp0. Isso alterará o diretório para a unidade do arquivo em lotes e, em seguida, para sua pasta.

Como alternativa, para #oneLinerLovers, como @Omni apontou nos comentários cd /d %~dp0, mudará a unidade e o diretório :)

Espero que isso ajude alguém.

Marvin Thobejane
fonte
23
cdpossui um parâmetro interno que alternará o inversor e a pasta:cd /d %~dp0
OmnipotentEntity 4/12
2
Você está certo e o /dargumento é útil, mas merece ser publicado como uma resposta alternativa candidata e não como um comentário a esta. Obrigado por apontar isso, porém, eu não sabia disso :)
Marvin Thobejane
4
você também pode usar '' pushd% ~ dp0 '' para alternar entre unidade e pasta
fmuecke
25

Ótimo exemplo do lançador de shell portátil da Strawberry Perl:

set drive=%~dp0
set drivep=%drive%
if #%drive:~-1%# == #\# set drivep=%drive:~0,-1%

set PATH=%drivep%\perl\site\bin;%drivep%\perl\bin;%drivep%\c\bin;%PATH%

não tenho certeza do que o 1 negativo está fazendo lá, mas funciona um prazer!

HansBKK
fonte
11
+1 muito útil. A instrução if verifica se uma barra invertida está presente e remove a barra invertida, se necessário. O negativo 1 na condição extrai o último caractere e a expressão na instrução set pega a cadeia de caracteres do caminho menos o último caractere (que é a barra invertida).
Matt
1
1 negativo é menos o último caractere. Leia substring variável
phuclv
12

Um exemplo seria bom - aqui está um exemplo trivial

for %I in (*.*) do @echo %~xI

lista apenas as EXTENSÕES de cada arquivo na pasta atual

para obter combinações de variáveis ​​mais úteis (também listadas na resposta anterior) no prompt do CMD execute: HELP FOR que contém esse trecho

Os modificadores podem ser combinados para obter resultados compostos:

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only
%~dp$PATH:I - searches the directories listed in the PATH
               environment variable for %I and expands to the
               drive letter and path of the first one found.
%~ftzaI     - expands %I to a DIR like output line
admin
fonte
eu recebi "~ xI foi inesperado neste momento." tentando o exemplo - é porque eu estou usando o Win 7?
precisa
Esta é uma boa informação, mas não consegue abordar a postagem original.
De Shan Baptiste