¿Qué significa% ~ dp0 y cómo funciona?

1024

Me parece %~dp0muy útil, y lo uso mucho para hacer que mis archivos por lotes sean más portátiles.

Pero la etiqueta en sí me parece muy críptica ... ¿Qué está ~haciendo? ¿ dpSignifica unidad y camino? ¿Hace 0referencia a %0la ruta al archivo por lotes que incluye el nombre del archivo?

¿O es solo una etiqueta extraña?

También me gustaría saber si es una característica documentada, o algo propenso a ser obsoleto.

Sebastián Grignoli
fuente
2
Tienes razón, Hellen. Esa pregunta no apareció cuando busqué% ~ dp0. Tal vez porque tiene% ~ d0 en su título en lugar de% ~ dp0.
Sebastián Grignoli
99
SymbolHound es ideal para realizar búsquedas en otros caracteres que no sean alfanuméricos. Por ejemplo, busque%~dp0 . Por lo general, encuentro que los mejores éxitos se refieren al contenido en SO.
DavidRR
SymbolHound no funcionó para mí con la búsqueda symbolhound.com/?q=%25~dp0 . Sin embargo, esto funcionó: google.com/search?q=%25~dp0 - solo diciendo ...
Kristopher
1
SymbolHound 2019: no funciona y uMatrix indica que se conecta a sitios de terceros como blockchain.info y paypalobjects.com.
Nils Lindemann

Respuestas:

811

Vocación

for /?

en la línea de comandos brinda ayuda sobre esta sintaxis (que también se puede usar fuera de FOR, este es solo el lugar donde se puede encontrar ayuda).

Además, se ha mejorado la sustitución de referencias variables FOR. Ahora puede usar la siguiente sintaxis 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

Los modificadores se pueden combinar para obtener resultados compuestos:

%~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

En los ejemplos anteriores,% I y PATH se pueden reemplazar por otros valores válidos. La sintaxis% ~ termina con un nombre de variable FOR válido. Elegir nombres de variables en mayúsculas como% I lo hace más legible y evita la confusión con los modificadores, que no distinguen entre mayúsculas y minúsculas.

Hay diferentes letras que puede usar como f"nombre de ruta completo", dletra de unidad, pruta y se pueden combinar. %~es el comienzo de cada una de esas secuencias y un número Iindica que funciona en el parámetro %I(donde %0está el nombre completo del archivo por lotes, tal como suponía).

Schnaader
fuente
2
No conozco a nadie más, pero aparece "El siguiente uso del operador de ruta en la sustitución de parámetros por lotes no es válido. Para formatos válidos, escriba CALL /? O FOR /? La sintaxis del comando es incorrecta". cuando se utiliza I. Tengo que usar en 0lugar de I. No sé si me he perdido algo o lo que sea, pero solo dejándolo saber a la gente.
mythofechelon
71
@BenHooper, Ies un marcador de posición para el índice variable. 0= el archivo de llamada, 1= argumento # 1, 2= argumento # 2, etc ...
Chris
99
Esta respuesta es buena. Y exhaustivo. Para un poco más breve, me gusta la respuesta a esta pregunta casi duplicada: stackoverflow.com/questions/112055/…
Frank Nocke
1
Esta respuesta es un poco confusa porque estas sustituciones se pueden usar fuera de FOR.
David
348

(Primero, me gustaría recomendar este útil sitio de referencia para el lote: http://ss64.com/nt/ )

Entonces solo otra explicación útil: http://htipe.wordpress.com/2008/10/09/the-dp0-variable/

La variable% ~ dp0

El ~% dp0 (que es un cero) variable cuando se hace referencia dentro de un archivo por lotes de Windows se expandirá a la d carta Rive y p ath de ese archivo por lotes.

Las variables% 0-% 9 se refieren a los parámetros de la línea de comandos del archivo por lotes. % 1-% 9 se refieren a los argumentos de la línea de comando después del nombre del archivo por lotes. % 0 se refiere al archivo por lotes en sí.

Si sigue el carácter de porcentaje (%) con un carácter de tilde (~), puede insertar uno o varios modificadores antes del número de parámetro para alterar la forma en que se expande la variable. El modificador d se expande a la letra de unidad y el modificador p se expande a la ruta del parámetro.

Ejemplo: supongamos que tiene un directorio en C: llamado bat_files, y en ese directorio hay un archivo llamado example.bat. En este caso,% ~ dp0 (combinando los modificadores d y p) se expandirá a C: \ bat_files.

Consulte este artículo de Microsoft para obtener una explicación completa.

Además, echa un vistazo a este hilo del foro .

Y una referencia más clara desde aquí :

  • %CmdCmdLine% devolverá toda la línea de comando como se pasó a CMD.EXE

  • %* devolverá el resto de la línea de comando comenzando en el primer argumento de la línea de comando (en Windows NT 4,% * también incluye todos los espacios iniciales)

  • %~dn devolverá la letra de unidad de% n (n puede variar de 0 a 9) si% n es una ruta válida o un nombre de archivo (sin UNC)

  • %~pn devolverá el directorio de% n si% n es una ruta válida o un nombre de archivo (sin UNC)

  • %~nn devolverá el nombre de archivo solo de% n si% n es un nombre de archivo válido

  • %~xn devolverá la extensión de archivo solo de% n si% n es un nombre de archivo válido

  • %~fn devolverá la ruta completa de% n si% n es un nombre de archivo o directorio válido

AGREGAR 1

Acabo de encontrar una buena referencia para el misterioso ~ operador de tilde.

La %~cadena se llama operador tilde por ciento . Lo puede encontrar en situaciones como: %~0.

La :~cadena se llama operador de tilde de colon . Puedes encontrarlo como %SOME_VAR:~0,-1%.

AGREGAR 2 - 1:12 PM 6/6/2018

%1-%9consulte los argumentos de la línea de comando. Si son no los valores ruta válida, %~dp1- %~dp9se expandirán para el mismo valor que %~dp0. Pero si son valores de ruta válidos, se expandirán a sus propios valor de controlador / ruta.

Por ejemplo: (batch.bat)

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

Ejecución 1:

D:\Workbench>batch arg1 arg2

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

Ejecución 2:

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

~dp0= D:\Workbench\
~dp1= c:\123\
~dp2= e:\abc\
smwikipedia
fuente
También tengo curiosidad por este concepto y encontré la buena aclaración aquí. Gracias Mingge ^ _ ^
Eugene
1
para mí se expande a c: \ bat_files \ (con separador de ruta posterior)
santa
Los enlaces al artículo de Microsoft y al hilo del foro ya no funcionan :(
wovano
151

La variable %0en un script por lotes se establece con el nombre del archivo por lotes en ejecución.

La ~dpsintaxis especial entre el %y el 0básicamente dice expandir la variable %0para mostrar la letra de unidad y la ruta, lo que le da el directorio actual que contiene el archivo por lotes.

Ayuda = Enlace

Andy White
fuente
@ Andy, ¿hay alguna forma de probar %0directamente en el cmd sin guardar un archivo .bat en el disco duro local?
Pacerier
El enlace está roto y no puedo encontrar el enlace correcto. Una edición pendiente todavía tiene el enlace roto.
George_E
45

% ~ dp0 se expande a la ruta actual del directorio del archivo por lotes en ejecución.

Para obtener una comprensión clara, creemos un archivo por lotes en un directorio.

C: \ script \ test.bat

con contenidos:

@echo off
echo %~dp0

Cuando lo ejecute desde el símbolo del sistema, verá este resultado:

C: \ script \

nulo
fuente
41

Otro consejo que sería una gran ayuda es que para establecer el directorio actual a una unidad diferente habría que utilizar %~d0en primer lugar, a continuación cd %~dp0. Esto cambiará el directorio a la unidad del archivo por lotes, luego cambiará a su carpeta.

Alternativamente, para #oneLinerLovers, como señaló @Omni en los comentarios cd /d %~dp0, cambiará tanto la unidad como el directorio :)

Espero que esto ayude a alguien.

Marvin Thobejane
fuente
23
cdtiene un parámetro incorporado que cambiará la unidad y la carpeta:cd /d %~dp0
OmnipotentEntity
2
Tiene razón y el /dargumento es útil, pero merece ser publicado como una respuesta alternativa candidata y no como un comentario a esta. Gracias por señalar esto, sin embargo, no lo sabía :)
Marvin Thobejane
44
también puede usar '' pushd% ~ dp0 '' para cambiar la unidad y la carpeta
fmuecke
25

Gran ejemplo del lanzador de shell portátil de 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%

No estoy seguro de lo que el 1 negativo está haciendo allí, ¡pero funciona de maravilla!

HansBKK
fuente
11
+1 muy útil. La instrucción if verifica si hay una barra diagonal inversa y la elimina si es necesario. El 1 negativo en la condición extrae el último carácter, y la expresión en la instrucción set toma la cadena de ruta menos el último carácter (que es la barra invertida).
Matt
1
negativo 1 es menos el último caracter. Leer subcadena variable
phuclv
12

Un ejemplo sería bueno: aquí hay uno trivial

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

enumera solo las EXTENSIONES de cada archivo en la carpeta actual

para combinaciones de variables más útiles (también enumeradas en la respuesta anterior) desde el indicador CMD execute: HELP FOR que contiene este fragmento

Los modificadores se pueden combinar para obtener resultados compuestos:

%~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
administración
fuente
Obtuve "~ xI fue inesperado en este momento". probando el ejemplo: ¿es porque estoy usando Win 7?
capítulo3
Esta es una buena información, pero no aborda la publicación original.
De Shan Baptiste el