Lorsque vous tapez cd..
sans espace entre cd
et ..
l'invite de commande Windows basculera avec plaisir dans le dossier parent. Y a-t-il une explication à ce comportement? La commande ne suit pas le format standard decommand<space>arguments
Aussi, pourquoi cela ne crée-t-il pas des résultats cohérents?
windows
command-line
command-line-arguments
Jonas Köritz
la source
la source
dir/a
ou la syntaxe VMS similaire.cd c:\program files
sans guillemets et cela fonctionne toujourscd..
marche? Parce que Microsoft a eu la peine de le faire fonctionner explicitement.cd
est une commande intégrée à l'interpréteur de commandes de Windows et Microsoft peut obliger leur interpréteur à faire ce qu'il veut. (Autre exemple,cd
il n'est pas nécessaire de citer les répertoires avec des espaces dans le nom.)Réponses:
Comme le notent certaines des 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’espacer.
Cependant, il existe un autre comportement qui est un peu moins bien compris et permet le "
cd..
" que vous demandez. Ce comportement permet également que "cd\
" fonctionne.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, notamment un point, une barre oblique ou une barre oblique inverse, les caractères précédents sont vérifiés pour déterminer s’il s’agit d’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. Cela est vrai pour la
cd
commande. Malheureusement, lors de la création d'un échantillon, j'ai constaté que cela ne se produisait pas avec lacopy
commande. Les résultats sont donc incohérents: ils ne sont pas nécessairement identiques pour toutes les commandes internes. Je n'ai pas poursuivi ma recherche pour comparer également (beaucoup) d'autres commandesdel
etdir
, par conséquent, 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 été posée à propos de la commande echo : Il s’agit d’une exception inhabituelle dans la mesure où elle
echo.
est assez bien connue des experts de DOS. Cela a probablement été documenté. Le comportement, au moins dans le CMD de Win7 , est que si la commande commence par "echo.
", la première période est ignorée. Ainsi, "echo..hi
" se transforme en sortie de ".hi
". La raison en est que "echo.
" peut être utilisé pour imprimer une ligne vierge. En revanche, avec Unix, vous pouvez le faire simplement en exécutant laecho
commande " " seule. Toutefois, sous DOS, l’exécution de laecho
commande " " seule produira le paramètre " echo " actuel . 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 voulez réellement imprimer le mot"Off
", alors"Echo.Off
"fait l'affaire (au moins avec les versions assez récentes de l' interpréteur de ligne de commande CMD de Microsoft .)Donc, au moins la
echo
commande a une explication semi-raisonnable. En ce qui concerne les commandes restantes, je pensais que les commandes internes étaient prioritaires. Cependant, quand 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 avec privilèges élevés afin d'éviter que le contrôle de compte d'utilisateur m'écrive 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, telles que COMMAND.COM à partir d'anciennes versions de MS-DOS ou des logiciels publiés par d'autres sociétés (COMMAND.COM de DR-DOS).
(Cette réponse est déjà assez longue, je n'inclus donc pas de commandes pour nettoyer tous les dégâts que j'ai causés sur mon système de fichiers. Il y a un petit peu de nettoyage, mais pas beaucoup.)
Voici un exemple qui prouve que la commande interne crée une priorité. (Je démontre également la capacité assez mal connue d’utiliser un double-point pour constituer un commentaire, ce qui fonctionne également dans les fichiers batch. Techniquement, dans les fichiers batch, il est traité comme une étiquette inaccessible par GOTO et se termine up étant plus rapide que la commande REM.)
Voici un exemple montrant qu'une copie , avec un chemin complet, n'utilise pas la même priorité (privilégiant la commande interne) que cd quand aucune extension n'est utilisée:
Mes premières découvertes indiquaient que ces résultats démontraient que le shell de ligne de commande donnait la priorité:
Cela montre clairement que le comportement n'est pas cohérent entre la commande copy (avec un nom de fichier complet, y compris une extension) et la commande cd (sans extension dans le nom du répertoire). Lors de l'utilisation d'une barre oblique inverse, la commande de copie (avec l'extension de nom de fichier complète) vérifie d'abord le système de fichiers, mais pas la commande cd (si le répertoire ne contient pas d'extension).
(Mise à jour: au début, je pensais que l'incohérence était basée sur un comportement différent entre les programmes. Plus tard, j'ai découvert que l'incohérence existait, mais était davantage causée par les paramètres fournis.)
En fait, même ces points ne sont pas tout à fait exacts, même si je semblais simplement démontrer chaque chose que je venais de dire. Le problème est que cette liste de points n’est pas assez précise pour être tout à fait exacte. (J'ai laissé des informations imprécises pour pouvoir comparer ces points et les vérifier assez facilement.)
Cependant, pour être plus précis, la première puce doit indiquer que le shell de ligne de commande donne la priorité:
Ce qui suit va démontrer pourquoi je fais cette distinction:
(Notez que la dernière commande de copie a recherché le fichier appelé \ needext , car la commande de copie interne a été utilisée. Le fichier \ needext.bat a été créé uniquement pour aider à montrer facilement qu'il n'a jamais été utilisé par les lignes de commande contenant le mot copy. .)
À ce stade, j’ai établi une certaine incohérence (avec le comportement de la commande copy ) lorsqu’une barre oblique inversée est utilisée ...
Ensuite, je démontrerai qu’il existe une certaine cohérence entre ces commandes. (Donc, il y a une cohérence ... euh ... parfois. Il se peut que nous n'ayons que de la cohérence, de manière incohérente.) Ce que je vais montrer maintenant, c'est que la commande cd se comporte plutôt comme la commande copy lorsque un point est utilisé. La commande copy utilise la commande interne, de même que la commande cd .
Ainsi, au cours de la session de test initiale qui a principalement porté sur les commandes cd et copy (avec quelques utilisations supplémentaires de md et un peu de del ), le seul moment où le système de fichiers a pris la priorité était avec la commande copy , puis Le système de fichiers n’était prioritaire que lorsque le chemin complet était utilisé.
Après un examen ultérieur, j’ai constaté que la commande cd donnait également la priorité au système de fichiers lors de l’utilisation d’une extension. Au moins, cela signifie que les commandes internes sont traitées un peu plus de cohérence entre elles. Cependant, cela signifie également que nous obtenons un comportement différent en fonction des noms des objets du système de fichiers (les fichiers ou les répertoires). Il semble que le comportement utilise une logique interne très obscure. Par conséquent, compter sur ce comportement pour fonctionner sur différents systèmes d’exploitation est probablement quelque chose de dangereux .
la source
ipconfig
par exemple fonctionne aussi.IPCONFIG/ALL
. Cependant, ce n'est pas ce dont je parlais. " Le comportement que vous décrivez " (dans votre question) était le fait de placer un point juste après le nom de la commande. Si je tape,IPConfig.
j'obtiens une erreur à propos d'une commande introuvable. De même (bien que cela ne soit pas lié au comportement que vous décriviez), si je tape,IPCONFIG\ALL
je peux alors exécuter un.\IPCONFIG\ALL.BAT
fichier personnalisé que j'ai créé. Donc/
, ne sont pas traités comme.
ou `\`copy.exe
oucopy.com
en cmd. Cela ne fonctionne pas - ce n'est pas un exécutable.ipconfig
, je ne suis pas d'accord avec votre conclusion. Cette question concerne ce qui est 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 arobase, voici les premiers caractères d'un utilisateur qui apparaissent ailleurs sur la page.) Je conviens que l'exécution de "copy.exe
" utilisera lacopy
commande interne (et passera.exe
). (Vous pouvez courir.\copy.exe
)Vous supposez qu'un nom de commande et ses arguments doivent être séparés par un espace, en particulier, 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, donccd
et..
sont tout simplement analysé comme deux jetons séparés.Habituellement, votre premier argument commence par un caractère alphabétique (par exemple, le début d'un chemin), ainsi, il "perdra" le nom de votre commande et provoquera une erreur ... mais ce n'est pas un problème de syntaxe. C'est une sémantique.
Vous pouvez voir le même effet au travail avec d'autres commandes, notamment
echo
:Dans ce cas, nous n'obtenons que deux points car la
echo
commande elle-même a une règle spéciale , de sorte que:ou, par extension, ceci:
affiche uniquement une ligne vide. C'est une commodité. Apparemment, cela a été mis en œuvre en ignorant une période de pointe dans l'argument.
Hé, c'est DOS / Batch. Vous voulez la santé mentale? :RÉ
la source
cd..
cd..
plus :)alias cd..='cd ..'
.
et..
qui apparaissent comme des répertoires dans tous les répertoires et autant que je sache , n'a jamais été destiné à attraper plus que cela. En fait, je considère la dissimulation modélisée comme un attribut de fichier comme une conception plus propre que si elle découle implicitement du nom de fichier..
noms de fichiers , ce qui signifiait que cela ne pouvait pas faire partie d'un nom de commande et devait donc faire partie de l'argument . Même si DOS avait divisé la commande en arguments de la même manière que les shells Unix, il placerait toujours un.
après la commande dans le premier argument, car cela n'aurait aucun sens de mettre un caractère non valide dans le nom de la commande.La
cd..
commande est correcte et elle a été définie comme telle dans l'interpréteur de commande d'origine,command.com
qui a ensuite été nommécmd.exe
.L'interpréteur de commandes sait comment traiter
cd..
car il.
s'agit d'un caractère spécial, tout comme\
.la source
echo.
fonctionne tout aussi bien, ce qui imprimera une ligne vide..
n'est pas supprimé, mais seulement un espace est ajouté.md.test
etmd .test
tous deux créent le répertoire.test
. Tapezcd.test
etcd .test
va changer dans le répertoire.test
.C'est un hack de compatibilité ascendante.
L'interpréteur de ligne de commande est conçu pour être rétrocompatible avec les commandes de l'interpréteur de commandes MSDOS d'origine, qui a été conçu pour être rétrocompatible avec l'interpréteur de commandes CP / M. Ni CP / M ni MSDOS n'autorisaient un
.
dans un nom de fichier (celui-ci était interprété comme un séparateur entre deux parties du nom de fichier, le nom de base et l'extension). Cela signifiait que (du moins pour les premières versions de DOS), l'interpréteur de commande pourrait l'identifier s'il atteignait un '.' (ou bien tout autre caractère qui était illégal dans un nom de fichier), il passait la fin du nom de la commande et figurait dans les arguments de la commande. C’était assez courant sous DOS et CP / M. Par exemple, ildir/w
s’agissait d’une commande très courante, équivalente à ladir /w
signification de la liste des fichiers au format horizontal.Aujourd'hui, '.' peut apparaître dans les noms de fichiers. Cela entraîne certaines complications lors de l'analyse des commandes, mais le shell identifie toujours un
.
début ne faisant pas partie d'un nom de fichier exact comme étant le début des arguments. Cela est principalement dû au fait que des millions d’utilisateurs se sont habitués à tapercd..
ou possèdent un grand nombre de fichiers de commandes contenant cette commandeecho.
ou un nombre quelconque de commandes similaires.la source