Question Pourquoi "cd .." fonctionne-t-il dans la ligne de commande Windows?


En tapant cd.. sans espace entre cd et .. l'invite de commande Windows passera volontiers au dossier parent. Y a-t-il une explication à ce comportement? La commande ne respecte pas le format standard de command<space>arguments

Working but shouldn't?

En outre, pourquoi cela ne crée-t-il pas des résultats cohérents?

echo..


86
2018-06-06 10:32


origine


La prémisse de votre question semble être brisée. Pouvez-vous fournir une preuve de votre affirmation selon laquelle cette syntaxe est incorrecte? - Lightness Races in Orbit
Je ne pense pas que "les arguments de commande <espace>" aient jamais été les la norme format en cmd (ou l'un de ses prédécesseurs); considérer par exemple dir/a ou la syntaxe VMS similaire. - grawity
cd est très spécial Vous pouvez taper cd c:\program files sans devis et ça marche toujours - phuclv
Voici un article très amusant qui explique les bizarreries de la logique du shell Windows et ce qu’il peut causer: thedailywtf.com/articles/The-Core-Launcher - vsz
Pourquoi cd.. travail? Parce que Microsoft a eu le souci de le rendre explicitement opérationnel. cd est une commande intégrée à l'interpréteur de commandes de Windows, et Microsoft peut demander à son interprète de faire ce qu'il veut. (Comme autre exemple, cd aussi n'a pas besoin de citer autour des répertoires avec des espaces dans le nom.) - jamesdlin


Réponses:


Parmi les autres réponses / commentaires, l’idée qu’il doit y avoir un espace après la commande n’est pas correcte. Un exemple bien connu est que vous pouvez taper une barre oblique après une commande, sans avoir besoin d'espace au préalable.

Cependant, il existe un autre comportement un peu moins compris et qui permetcd.."que vous demandez à propos. Ce comportement permet également"cd\" travailler.

Le comportement que vous décrivez est cohérent pour toutes les commandes internes à l'interpréteur de ligne de commande. Si vous avez certains symboles, y compris un point, une barre oblique ou une barre oblique inverse, les caractères précédents sont vérifiés pour voir s'ils sont une commande interne au shell "interpréteur de ligne de commande" (CMD.EXE ou son prédécesseur COMMAND.COM ).

Cela peut être fait avant de vérifier si le mot peut faire référence à un fichier ou à un sous-répertoire. C'est vrai pour le cd commander. Tragiquement, en faisant un échantillon, j'ai constaté que cela ne se produit pas avec le copy commande, les résultats sont donc incohérents: ils ne sont pas nécessairement les mêmes avec toutes les commandes internes. Je n'ai pas continué ma recherche pour comparer (beaucoup) d'autres lignes de commandes del et dir, alors je suggère simplement d'être extrêmement prudent si vous essayez de vous fier à ce qui se passe sans espace.

Maintenant, la question a également demandé à propos de la écho commande: Ceci est une exception inhabituelle, en ce sens que je pense echo. est assez bien connu des experts de DOS. Cela a probablement été documenté. Le comportement, au moins dans Win7 CMD, est-ce si la commande commence par "echo.", alors la première période est ignorée. Donc,"echo..hi"tourne en sortie de".hi". La raison en est que"echo."peut être utilisé pour imprimer une ligne vide. En revanche, avec Unix, vous pouvez le faire simplement en exécutant le"echo"commande par lui-même. Cependant, sous DOS, exécutez le"echo"la commande seule produira le courant"écho"réglage. De même, DOS traite"Echo *Off*" et "Echo *On*"en tant que valeurs spéciales qui modifient le paramètre d'écho actuel. Si vous souhaitez réellement imprimer le mot"Off", puis "Echo.Off"fait le tour (au moins avec les versions récentes de Microsoft) CMD interprète en ligne de commande.)

Donc, au moins le echo commande a une explication semi-raisonnable. En ce qui concerne les commandes restantes, je pensais que les commandes internes étaient prioritaires. Cependant, lorsque j'ai essayé de faire des tests, j'ai trouvé que c'était plutôt incohérent. Je le démontre à travers quelques exemples que j'ai documentés ici.


Voici quelques exemples. J'ai utilisé une invite de commande élevée, de sorte que l'UAC ne me reprocherait pas de m'écrire dans le répertoire racine. Cela a été fait avec CMD.EXE de Microsoft Windows 7. Je soupçonne que les comportements peuvent être différents avec d'autres versions, comme COMMAND.COM à partir d'anciennes versions de MS-DOS ou avec des logiciels publiés par d'autres sociétés (COMMAND.COM de DR-DOS).

(Cette réponse est déjà assez longue, donc je n'inclus pas les commandes pour nettoyer tout le bazar que j'ai créé sur mon système de fichiers. Il y a un petit nettoyage, mais pas beaucoup.)

Voici un exemple qui prouve que la commande interne crée la priorité. (Je démontre également la capacité plutôt peu connue d’utiliser un double deux-points pour être effectivement un commentaire, qui fonctionne également bien dans les fichiers de commandes. Techniquement, dans les fichiers de commandes, GOTO être plus rapide que la commande REM.)

C: \ quelque chose> md cd
C: \ quelque chose> écho echo subdir >> cd \ a.bat
C: \ quelque chose> md \ a
C: \ quelque chose> . \ cd \ a.bat
subdir

C: \ quelque chose> :: Cela a couru du sous-répertoire
C: \ quelque chose> cd \ a
C: \ a> :: Cela a changé mon répertoire actuel, donc CD a préséance

Mettre à jour: Après une expérimentation supplémentaire, j'ai constaté que la CD La commande ne prévaut que sur le système de fichiers si le répertoire spécifié n'inclut pas de point. Donc, si vous avez un répertoire nommé "une chauve-souris", alors vous pouvez courir"**cd\a.bat**"et le fichier de commandes sera exécuté.

Cette exploration de comportements moins courants (puisque la plupart des répertoires ne comportent probablement pas de périodes) m'a amené à mettre à jour mes conclusions. Il se trouve que le CD commande se comporte en fait plus similaire à la copie commande que je pensais initialement.

Bien que j'ai d'abord pensé que le CD et copie les commandes se comportaient différemment, j'ai maintenant compris que c'était à cause de la structure des noms que je fournissais. Cependant, j'ai passé en revue mes résultats antérieurs et déterminé que mes tests antérieurs documentés aident à montrer une partie de la différence entre ce qui se produit lorsqu'un nom inclut une période et une extension et quand ce n'est pas le cas. Donc, j'inclus toujours mes anciennes conclusions ci-dessous (la plupart du temps inchangées, mais avec quelques mises à jour très mineures, donc ce que je dis est exact).


105
2018-06-06 19:43



"Le comportement que vous décrivez est cohérent pour toutes les commandes internes à l'interpréteur de ligne de commande." ipconfig par exemple fonctionne aussi. - Jonas Köritz
@ JonasKöritz: Non. Vous pouvez mettre une barre oblique (avant) juste après la commande "IPConfig"et cela fonctionnera, par ex. IPCONFIG/ALL. Cependant, ce n'est pas ce dont je parlais. "Le comportement que vous décrivez"(dans votre question) était le comportement de placer un point juste après le nom de la commande. Si je tape IPConfig. alors je reçois une erreur à propos d'une commande non trouvée. De même (bien que cela ne soit pas lié au comportement que vous décriviez), si je tape IPCONFIG\ALLalors je peux exécuter une coutume .\IPCONFIG\ALL.BAT fichier que j'ai fait. Alors /ne sont pas traités comme . ou `\` - TOOGAM
J'accepterai votre réponse pour apprécier le travail et les recherches nécessaires à sa création! - Jonas Köritz
@Calchas Simple test - essayez d'exécuter copy.exe ou copy.com en cmd. Cela ne fonctionne pas - ce n'est pas un exécutable. - Luaan
@Luann: Concernant ipconfig, Je ne suis pas d'accord avec votre conclusion. Cette question concerne ce qui a été tapé au début d'une ligne de commande. Windows / DOS identifie les exécutables par extension de nom de fichier, vous ne pouvez donc pas exécuter un programme appelé "ipconfig" sans extension (sous Windows, contrairement à Unix qui le permet). En ce qui concerne le commentaire suivant, je ne sais pas qui est "Calchas". (Lorsque vous spécifiez un signe, les suivants sont généralement les premiers caractères d'un utilisateur qui apparaît ailleurs sur la page.) Je suis d'accord, en cours d'exécution "copy.exe"utilisera l'interne copy commande (et passe .exe). (Tu peux courir .\copy.exe) - TOOGAM


Vous supposez qu'un nom de commande et ses arguments doivent être séparés par un espace, mais ce n'est pas vrai. Tant que l'invocation peut être interprétée sans ambiguïté, l'invocation est valide.

Dans ce cas, le premier argument commence par . et . ne peut pas faire partie du nom de la commande, donc cd et .. sont simplement analysés comme deux jetons distincts.

Habituellement, votre premier argument commencera par un caractère alphabétique (par exemple, le début d'un chemin), de sorte qu'il «perdra» votre nom de commande et provoquera une erreur… mais ce n'est pas un problème de syntaxe. C'est sémantique.

Vous pouvez voir le même effet au travail avec d'autres commandes, y compris echo:

echo...
..

Dans ce cas, nous n'obtenons que deux périodes car la echo la commande elle-même a une règle spéciale, de sorte que les éléments suivants:

echo .

ou, par extension, ceci:

echo.

génère uniquement une ligne vide. C'est une commodité. Apparemment, il a été mis en œuvre en ignorant une période de référence dans l'argument.

Hé, c'est DOS / Batch. Vous voulez la santé mentale? :RÉ


41
2018-06-06 11:35



J'ai supposé cela parce qu'il est unique à la ligne de commande Windows, bash par exemple ne vous permettra pas de faire cd.. - Jonas Köritz
@ JonasKöritz: C'est un programme complètement différent sur un système d'exploitation entièrement différent. Mon vélo ne permet pas cd.. non plus :) - Lightness Races in Orbit
@ JonasKöritz: alias cd..='cd ..' - mouviciel
@LightnessRacesinOrbit: À l'origine, c'était un raccourci de filtrage . et .. qui apparaissent comme des répertoires dans tous les autres répertoires et pour autant que je sache, ils n'ont jamais été conçus pour capturer plus que cela. En fait, je considère que la modélisation par masquage comme un attribut de fichier est un concept plus net que de le suivre implicitement à partir du nom du fichier. - Joey
@joey - Je pense que le point le plus pertinent n'est pas que l'approche DOS était plus simple, mais que DOS n'a pas permis . dans les noms de fichiers, ce qui le signifiait ne pouvait pas faire partie d'un nom de commande donc doit avoir fait partie de l'argument. Même si DOS avait divisé la commande en arguments comme le faisaient les shells Unix, cela placerait toujours un . après la commande dans le premier argument, car cela n'aurait aucun sens de mettre un caractère invalide dans le nom de la commande. - Jules


le cd..la commande est correcte et elle a été définie comme celle de l'interpréteur de commandes d'origine command.comqui plus tard a été nommé cmd.exe.

L'interprète de commande sait comment traiter cd.., car . est un personnage spécial, tout comme \.


19
2018-06-06 10:43



Je suppose que le problème principal est que la commande ne peut pas être "syntaxiquement incorrecte" car la syntaxe n'est formellement spécifié nulle part, donc, si l'implémentation principale (cmd.exe et / ou MS-DOS) l'accepte, elle doit être correcte. - grawity
De plus, CD n'est pas un programme, mais une commande interne. Semblable à Echo, qui est également une commande interne, il n'a pas besoin d'avoir d'espace pour fonctionner. echo. fonctionne aussi bien, ce qui imprimera une ligne vide. - LPChip
@Overmind echoe ne fonctionnera pas non plus, il en va de même avec cd, echo, md, etc. - LPChip
@ JonasKöritz, le . n'est pas abandonné mais juste un espace est ajouté. md.test et md .test tous deux créent le répertoire .test. Dactylographie cd.test et cd .test va changer dans le répertoire .test. - daniel.neumann
@ JonasKöritz: Parce que la syntaxe n'a jamais été un argument de commande-espace. - Lightness Races in Orbit


C'est un piratage de compatibilité ascendante.

L'interpréteur de ligne de commande est conçu pour être compatible avec les commandes de l'interpréteur de commandes MSDOS d'origine, conçu pour être compatible avec l'interpréteur de commandes CP / M. Ni le CP / M, ni le MSDOS ne permettaient . dans un nom de fichier (il a été interprété comme un séparateur entre deux parties du nom de fichier, le nom de base et l’extension). Cela signifiait que (au moins pour les premières versions de DOS), l'interpréteur de commandes pouvait l'identifier s'il atteignait un '.' (ou tout autre caractère illégal dans un nom de fichier), il passait la fin du nom de la commande et figurait dans les arguments de la commande. Cela était assez communément utilisé sous DOS et CP / M - par exemple, dir/w était une commande très commune, équivalente à dir /w ce qui signifie que la liste des fichiers dans un format horizontal.

Aujourd'hui, '.' peut apparaître dans les noms de fichiers. Cela provoque certaines complications dans la façon d'analyser les commandes, mais le shell encore identifie un . cela ne fait pas partie d'un nom de fichier exact comme étant le début des arguments. Cela est nécessaire en grande partie parce que des millions d’utilisateurs se sont habitués à taper cd.. ou avoir un grand nombre de fichiers de commandes contenant cela ou echo. ou n'importe quel nombre d'autres commandes similaires.


11
2018-06-06 14:55