Al escribir cd..
sin un espacio entre cd
y ..
el símbolo del sistema de Windows cambiará felizmente a la carpeta principal. ¿Hay alguna explicación para este comportamiento? El comando no sigue el formato estándar decommand<space>arguments
Además, ¿por qué esto no crea resultados consistentes?
windows
command-line
command-line-arguments
Jonas Köritz
fuente
fuente
dir/a
o la sintaxis VMS similar.cd c:\program files
sin comillas y aún funcionacd..
funciona? Porque Microsoft pasó por la molestia de hacerlo explícitamente funcionar.cd
es un comando integrado en el intérprete de comandos de Windows, y Microsoft puede hacer que su intérprete haga lo que quiera. (Como otro ejemplo,cd
tampoco es necesario citar alrededor de directorios con espacios en el nombre.)Respuestas:
Como señalan algunas de las otras respuestas / comentarios, la idea de que debe haber un espacio después del comando no es correcta. Un ejemplo bien conocido es que puede escribir una barra diagonal después de un comando, sin necesidad de un espacio primero.
Sin embargo, hay otro comportamiento que es un poco menos comprendido y permite el "
cd..
" que está preguntando. Este comportamiento también permite que "cd\
" funcione.El comportamiento que describe es coherente para todos los comandos internos del intérprete de línea de comandos. Si tiene ciertos símbolos, incluido un punto, una barra diagonal o una barra diagonal inversa, los caracteres anteriores se verifican para ver si son un comando interno del shell "intérprete de línea de comandos" (CMD.EXE o su predecesor COMMAND.COM )
Esto se puede hacer antes de verificar si la palabra puede referirse a un archivo o subdirectorio. Eso es cierto para el
cd
comando. Trágicamente, al hacer una muestra, descubrí que esto no sucede con elcopy
comando, por lo que los resultados son inconsistentes: no son necesariamente los mismos con todos los comandos internos. No continué mi búsqueda para comparar (mucho) otras líneas de comandosdel
ydir
, por lo tanto, simplemente sugiero ser extremadamente cuidadoso si intentas confiar en lo que sucede sin un espacio.Ahora, la pregunta también se hizo sobre el comando echo : esta es una excepción inusual, ya que creo que
echo.
es bastante conocida por los expertos de DOS. Esto probablemente fue documentado. El comportamiento, al menos en el CMD de Win7 , es que si el comando comienza con "echo.
", se ignora el primer período. Entonces, "echo..hi
" se convierte en salida de ".hi
". La razón de esto es para que "echo.
" se pueda usar para imprimir una línea en blanco. En contraste, con Unix, puede hacer esto simplemente ejecutando elecho
comando " " por sí mismo. Sin embargo, en DOS, ejecutar elecho
comando " " por sí solo generará la configuración actual de " eco ". Del mismo modo, DOS trata "Echo *Off*
" y "Echo *On*
"como valores especiales que cambian la configuración de eco actual. Si realmente desea imprimir la palabra"Off
", entonces"Echo.Off
"hace el truco (al menos con versiones lo suficientemente recientes del intérprete de línea de comandos CMD de Microsoft ).Entonces, al menos el
echo
comando tiene una explicación semi-razonable. En cuanto a los comandos restantes, solía pensar que los comandos internos tenían prioridad. Sin embargo, cuando intenté hacer algunas pruebas, descubrí que en realidad es bastante inconsistente. Lo demuestro a través de algunos ejemplos que documenté aquí.Aquí hay unos ejemplos. Utilicé un símbolo del sistema elevado, para que UAC no se quejara de que escribiera en el directorio raíz. Esto se hizo con CMD.EXE de Microsoft Windows 7. Sospecho que los comportamientos pueden ser diferentes con otras versiones, como COMMAND.COM de versiones anteriores de MS-DOS, o software lanzado por otras compañías (COMMAND.COM de DR-DOS).
(Esta respuesta ya es bastante larga, por lo que no incluyo comandos para limpiar todo el desorden que hice en mi sistema de archivos. Hay un poco de limpieza, pero no mucho).
Aquí hay un ejemplo que prueba que el comando interno crea precedencia. (También demuestro la capacidad poco conocida de usar dos puntos dobles para ser un comentario efectivo, que también funciona bien en archivos por lotes. Técnicamente, en archivos por lotes, se procesa como una etiqueta que GOTO no puede alcanzar, y finaliza siendo más rápido que el comando REM.)
Aquí hay un ejemplo que muestra que la copia , con una ruta completa, no usa la misma precedencia (favoreciendo el comando interno) que cd cuando no se usa ninguna extensión:
Mis primeros hallazgos indicaron que estos resultados demuestran que la línea de comandos da prioridad:
Esto demuestra claramente que el comportamiento no es consistente entre el comando copiar (con un nombre de archivo completo que incluye una extensión) y el comando cd (sin una extensión como parte del nombre del directorio). Cuando se utiliza una barra diagonal inversa, el comando copiar (con la extensión completa del nombre de archivo) verificará primero el sistema de archivos, pero el comando cd no (si el directorio no contiene una extensión).
(Actualización: Al principio, pensé que la inconsistencia se basaba en un comportamiento diferente entre los programas. Más tarde, descubrí que la inconsistencia existía, pero se debió más a los parámetros proporcionados).
En realidad, incluso esas viñetas no son del todo precisas, aunque parece que demostré cada cosa individual que acabo de decir. El problema es que esa lista de viñetas no es lo suficientemente precisa como para ser completamente precisa. (Dejé las cosas imprecisas para que esas viñetas pudieran compararse con relativa facilidad y comprobarse con relativa facilidad).
Sin embargo, para ser más precisos, el primer punto de viñeta debe señalar que el shell de la línea de comando da prioridad:
Lo siguiente demostrará por qué estoy haciendo esa distinción:
(Tenga en cuenta que el último comando de copia buscó el archivo llamado \ needext , porque se usó el comando de copia interno . El archivo \ needext.bat solo se creó para ayudar a mostrar fácilmente que nunca fue utilizado por las líneas de comando que incluían la palabra copiar .)
En este punto, establecí algunas inconsistencias (con el comportamiento del comando copiar ) cuando se usa una barra invertida ...
A continuación, demostraré que hay cierta coherencia entre estos comandos. (Entonces, hay consistencia ... um ... a veces. Es posible que solo tengamos consistencia, de manera inconsistente.) Lo que mostraré a continuación es que el comando cd se comporta como el comando copiar cuando se usa un punto. El comando copiar usa el comando interno, y también el comando cd .
Entonces, durante la sesión de prueba inicial que se centró principalmente en los comandos cd y copy (con algún uso adicional de md y un poco de del ), la única vez que realmente teníamos prioridad en el sistema de archivos era con el comando copy , y luego el El sistema de archivos solo tenía prioridad cuando se usaba la ruta completa.
Después de una revisión posterior, descubrí que el comando cd también le daba prioridad al sistema de archivos cuando usaba una extensión. Al menos esto significa que los comandos internos están siendo tratados un poco más consistentes entre sí. Sin embargo, también significa que obtenemos un comportamiento diferente según los nombres de los objetos del sistema de archivos (los archivos o directorios). Parece que el comportamiento está utilizando una lógica interna muy, muy oscura. Por lo tanto, contar con este comportamiento para trabajar en diferentes sistemas operativos es algo que probablemente consideraría inseguro .
fuente
ipconfig
por ejemplo funciona también.IPCONFIG/ALL
. Sin embargo, eso no es de lo que estaba hablando. " El comportamiento que usted describe " (en su pregunta) fue el comportamiento de colocar un punto justo después del nombre del comando. Si escriboIPConfig.
, recibo un error sobre un comando que no se encuentra. De manera similar (aunque esto no está relacionado con el comportamiento que estaba describiendo), si escriboIPCONFIG\ALL
, puedo ejecutar un.\IPCONFIG\ALL.BAT
archivo personalizado que hice. Por lo tanto/
, no se tratan como.
o `\`copy.exe
ocopy.com
en cmd. No funciona, no es un ejecutable.ipconfig
, no estoy de acuerdo con tu conclusión. Esta pregunta es acerca de lo que está escrito al comienzo de una línea de comando. Windows / DOS identifica los ejecutables por extensión de nombre de archivo, por lo que no puede ejecutar un programa llamado "ipconfig" sin una extensión (en Windows, a diferencia de Unix que lo permite). Con respecto al siguiente comentario, no sé quién es "Calchas". (Cuando especifica un signo at, los siguientes son generalmente los primeros caracteres de un usuario que aparece en otra parte de la página). Estoy de acuerdo, al ejecutar "copy.exe
" se usará elcopy
comando interno (y pasar.exe
). (Puedes correr.\copy.exe
)Asume que un nombre de comando y sus argumentos deben estar separados por un espacio, específicamente, pero esto no es cierto. Mientras la invocación se pueda interpretar sin ambigüedades, la invocación es válida.
En este caso, el primer argumento comienza con
.
y.
no puede ser parte del nombre del comando, asícd
y..
simplemente se analiza como dos fichas separadas.Por lo general, su primer argumento comenzará con un carácter alfabético (por ejemplo, el comienzo de una ruta), por lo que "sangrará" en el nombre de su comando y causará un error ... pero eso no es un problema de sintaxis. Es semántico.
Puede ver el mismo efecto en el trabajo con otros comandos, que incluyen
echo
:En este caso, obtenemos solo dos puntos porque el
echo
comando en sí tiene una regla especial , de modo que lo siguiente:o, por extensión, esto:
genera solo una línea vacía. Es una conveniencia. Aparentemente se ha implementado ignorando un punto principal en el argumento.
Hola, esto es DOS / Batch. ¿Quieres cordura? :RE
fuente
cd..
cd..
:)alias cd..='cd ..'
.
y..
que aparecen como directorios en cualquier otro directorio y, por lo que sé, nunca tuvo la intención de atrapar más que eso. De hecho, considero que la ocultación modelada como atributo de archivo es un diseño más limpio que tenerlo implícitamente del nombre del archivo..
nombres de archivo , lo que significaba que no podía ser parte del nombre de un comando, por lo tanto, debe haber sido parte del argumento . Incluso si DOS hubiera dividido el comando en argumentos como lo hacen los shells de Unix, aún colocaría un.
comando después del comando en el primer argumento, porque no tendría sentido poner un carácter no válido en el nombre del comando.El
cd..
comando es correcto y se definió así en el intérprete de comandos originalcommand.com
que más tarde se denominócmd.exe
.El intérprete de comandos sabe cómo procesar
cd..
, porque.
es un carácter especial, al igual que\
.fuente
echo.
funciona igual de bien, lo que imprimirá una línea vacía..
no se descarta, solo se agrega un espacio.md.test
ymd .test
ambos crean el directorio.test
. Escribiendocd.test
ycd .test
cambiará al directorio.test
.Es un truco de compatibilidad con versiones anteriores.
El intérprete de línea de comandos está diseñado para ser retrocompatible con los comandos del intérprete de comandos MSDOS original, que fue diseñado para ser retrocompatible con el intérprete de comandos CP / M. Ni CP / M ni MSDOS permitieron un
.
en un nombre de archivo (se interpretó como un separador entre dos partes del nombre de archivo, el nombre base y la extensión). Esto significaba que (al menos para las primeras versiones de DOS), el intérprete de comandos podría identificar eso si alcanzaba un '.' (o, de hecho, cualquier otro carácter que fuera ilegal en un nombre de archivo) pasó el final del nombre del comando y entró en los argumentos del comando. Esto se usaba con bastante frecuencia tanto en DOS como en CP / M; por ejemplo,dir/w
era un comando muy común, equivalente aldir /w
significado de listar archivos en formato horizontal.Hoy en día, '.' puede aparecer en nombres de archivo. Esto causa algunas complicaciones en cómo analizar los comandos, pero el shell aún identifica un
.
que no es parte de un nombre de archivo exacto como el comienzo de los argumentos. Esto es necesario en gran medida porque millones de usuarios se han acostumbrado a escribircd..
o tienen un gran número de archivos por lotes que contienen eseecho.
o cualquier otro número de comandos similares.fuente