Questão Por que “cd ..” funciona na linha de comando do Windows?


Ao digitar cd.. sem um espaço entre cd e .. o prompt de comando do Windows ficará feliz em mudar para a pasta pai. Existe uma explicação para esse comportamento? O comando não segue o formato padrão de command<space>arguments

Working but shouldn't?

Além disso, por que isso não cria resultados consistentes?

echo..


86


origem


A premissa da sua pergunta parece estar quebrada. Você pode fornecer alguma evidência para sua afirmação de que isso está sintaticamente incorreto? - Lightness Races in Orbit
Eu não acho que "argumentos de <espaço> de comando" tenham sido os padrão formato em cmd (ou qualquer um dos seus predecessores); considere por exemplo dir/a ou a sintaxe VMS semelhante. - grawity
cd é muito especial. Você pode digitar cd c:\program files sem aspas e ainda funciona - phuclv
Aqui está um artigo muito divertido que explica as peculiaridades da lógica de shell do Windows e o que pode causar: thedailywtf.com/articles/The-Core-Launcher - vsz
Porque cd.. trabalhos? Porque a Microsoft teve o trabalho de explicitamente fazê-lo funcionar. cd é um comando embutido no interpretador de comandos do Windows, e a Microsoft pode fazer com que seus intérpretes façam o que quiserem. (Como outro exemplo, cd também não precisa de citar em torno de diretórios com espaços no nome. - jamesdlin


Respostas:


Como algumas das outras respostas / comentários observam, a ideia de que deve haver um espaço após o comando não está correta. Um exemplo bem conhecido é que você pode digitar uma barra depois de um comando, sem precisar de um espaço primeiro.

No entanto, há outro comportamento que é um pouco menos compreendido e permite que "cd.."que você está perguntando. Esse comportamento também permite"cd\" trabalhar.

O comportamento que você descreve é ​​consistente para todos os comandos internos do interpretador de linha de comando. Se você tiver determinados símbolos, incluindo um ponto final, barra ou barra invertida, os caracteres anteriores serão verificados para ver se eles são um comando interno ao shell "interpretador de linha de comando" (CMD.EXE ou seu predecessor COMMAND.COM ).

Isso pode ser feito antes de verificar se a palavra pode se referir a um arquivo ou subdiretório. Isso é verdade para o cd comando. Tragicamente, ao fazer uma amostra, descobri que isso não acontece com o copy comando, então os resultados são inconsistentes: eles não são necessariamente os mesmos com todos os comandos internos. Eu não continuei minha busca para também comparar (muito) a linha de outros comandos del e dir, então eu simplesmente sugiro ser extremamente cuidadoso se você tentar confiar no que acontece sem um espaço.

Agora, a questão também perguntou sobre o eco comando: Esta é uma exceção incomum, em que eu acho echo. é bastante conhecido pelos especialistas em DOS. Isso provavelmente foi documentado. O comportamento, pelo menos no Win7 CMD, é que se o comando começar com "echo.", então o primeiro período é ignorado. Então,"echo..hi"se transforma em saída de".hi". A razão para isso é que"echo."pode ​​ser usado para imprimir uma linha em branco. Em contraste, com o Unix, você pode fazer isso simplesmente executando o"echo"comando sozinho. No entanto, no DOS, executando o"echo"comando por si só irá produzir o atual"eco"configuração. Da mesma forma, o DOS trata"Echo *Off*"e"Echo *On*"como valores especiais que alteram a configuração de eco atual. Se você realmente deseja imprimir a palavra"Off", então "Echo.Off"faz o truque (pelo menos com versões recentes suficientes da Microsoft CMD intérprete de linha de comando.)

Então, pelo menos o echo comando tem uma explicação semi-razoável. Quanto aos comandos restantes, costumava pensar que os comandos internos tinham prioridade. No entanto, quando tentei fazer alguns testes, descobri que na verdade é bastante inconsistente. Eu demonstro isso através de alguns exemplos que documentei aqui.


Aqui estão alguns exemplos. Eu usei um prompt de comando elevado, para que o UAC não se queixasse de eu escrever no diretório raiz. Isso foi feito com o CMD.EXE do Microsoft Windows 7. Eu suspeito que os comportamentos podem ser diferentes com outras versões, como o COMMAND.COM de versões mais antigas do MS-DOS ou o software lançado por outras empresas (Command.com do DR-DOS).

(Essa resposta já é bastante longa, então eu não estou incluindo comandos para limpar toda a bagunça que fiz no meu sistema de arquivos. Há um pouquinho de limpeza, mas não muito.)

Aqui está um exemplo que prova que o comando interno cria precedência. (Eu também demonstro a capacidade pouco conhecida de usar dois-pontos duplos para efetivamente ser um comentário, que também funciona bem em arquivos batch. Tecnicamente, em arquivos em lote, ele é processado como um rótulo que não pode ser alcançado pelo GOTO e termina sendo mais rápido que o comando REM.)

C: \ alguma coisa> md cd
C: \ alguma coisa> eco echo subdir >> cd \ a.bat
C: \ alguma coisa> md \ a
C: \ alguma coisa> . \ cd \ a.bat
subdirecionar

C: \ alguma coisa> :: Isso correu do subdir
C: \ alguma coisa> cd \ a
C: \ a> :: Isso mudou meu diretório atual, então CD tomou precedência

Atualizar: Após mais experimentos, descobri que o CD O comando só tem precedência sobre o sistema de arquivos se o diretório especificado não incluir um período. Então, se você tem um diretório chamado "um morcego", então você pode correr"**cd\a.bat**"e o arquivo de lote será executado.

Essa exploração de comportamento menos comum (já que a maioria dos diretórios provavelmente não possui períodos) levou-me a atualizar minhas descobertas. Acontece que o CD comando está realmente se comportando mais semelhante ao cópia de comando do que eu pensava inicialmente.

Embora eu inicialmente pensasse que o CD e cópia de os comandos estavam se comportando de maneira diferente, agora percebi que é por causa do padrão dos nomes que eu estava fornecendo. Ainda assim, analisei meus resultados anteriores e concluí que meus testes documentados anteriores ajudam a mostrar algumas das diferenças entre o que acontece quando um nome inclui um período e uma extensão e quando não. Então, eu ainda estou incluindo minhas descobertas mais antigas abaixo (praticamente inalteradas, mas com algumas atualizações muito pequenas, então o que eu digo é preciso).


105



"O comportamento que você descreve é ​​consistente para todos os comandos internos ao interpretador de linha de comando." ipconfig por exemplo funciona também. - Jonas Köritz
@ JonasKöritz: Não. Você pode colocar uma barra (avançar) logo após o comando "IPConfig"e isso vai funcionar, por ex. IPCONFIG/ALL. No entanto, não é disso que eu estava falando. "O comportamento que você descreve"(na sua pergunta) foi o comportamento de colocar um período logo após o nome do comando. Se eu digitar IPConfig. então eu recebo um erro sobre um comando não ser encontrado. Da mesma forma (embora isso não esteja relacionado ao comportamento que você estava descrevendo), se eu digitar IPCONFIG\ALLentão eu posso executar um costume .\IPCONFIG\ALL.BAT arquivo que eu fiz. assim /não são tratados como . ou `\` - TOOGAM
Aceitarei sua resposta para apreciar o trabalho e a pesquisa necessários para criá-la! - Jonas Köritz
@Calchas Teste simples - tente executar copy.exe ou copy.com em cmd. Não funciona - não é um executável. - Luaan
@ Luann: Em relação ipconfigEu não concordo com a sua conclusão. Esta questão é sobre o que é digitado no início de uma linha de comando. O Windows / DOS identifica executáveis ​​por extensão de nome de arquivo, portanto você não pode executar um programa chamado "ipconfig" sem uma extensão (no Windows, ao contrário do Unix, que permite isso). Em relação ao próximo comentário, não sei quem é o "Calchas". (Quando você especifica um sinal de arroba, segue geralmente os primeiros caracteres de um usuário que aparecem em outro lugar na página.) Concordo, executando "copy.exe"usará o interno copy comando (e passe .exe). (Você pode correr .\copy.exe) - TOOGAM


Você assume que um nome de comando e seus argumentos devem ser separados por um espaço, especificamente, mas isso não é verdade. Contanto que a invocação possa ser interpretada de forma não ambígua, a invocação é válida.

Neste caso, o primeiro argumento começa com . e . não pode fazer parte do nome do comando, então cd e .. são simplesmente analisados ​​como dois tokens separados.

Normalmente, seu primeiro argumento será iniciado com um caractere alfabético (por exemplo, o início de um caminho), assim ele "sangrará" no nome do seu comando e causará um erro ... mas isso não é um problema de sintaxe. É uma semântica.

Você pode ver o mesmo efeito no trabalho com outros comandos, incluindo echo:

echo...
..

Neste caso, temos apenas dois períodos porque a echo comando em si tem uma regra especial, de modo que o seguinte:

echo .

ou, por extensão, isso:

echo.

produz apenas uma linha vazia. É uma conveniência. Aparentemente, ele foi implementado ignorando um período inicial no argumento.

Ei, isso é DOS / Batch. Você quer sanidade? : D


41



Eu assumi isso porque é exclusivo para a linha de comando do windows, bash por exemplo não permitirá que você faça cd.. - Jonas Köritz
@ JonasKöritz: Esse é um programa completamente diferente em um sistema operacional totalmente diferente. Minha bicicleta não permite cd.. ou :) - Lightness Races in Orbit
@ JonasKöritz: alias cd..='cd ..' - mouviciel
@LightnessRacesinOrbit: Originalmente era um atalho de filtragem . e .. que aparecem como diretórios em todos os outros diretórios e, tanto quanto eu sei, nunca foi destinado a pegar mais do que isso. Na verdade, considero o hidden-ness modelado como atributo de arquivo um design mais limpo do que seguir implicitamente a partir do nome do arquivo. - Joey
@joey - Eu acho que o ponto mais relevante não é que a abordagem DOS fosse mais simples, é que DOS não permitiu . em nomes de arquivos, o que significava não poderia fazer parte de um nome de comando assim sendo deve ter sido parte do argumento. Mesmo se o DOS tivesse dividido o comando em argumentos, como acontece com as unidades Unix, ainda assim . após o comando no primeiro argumento, porque não faria sentido colocar um caractere inválido no nome do comando. - Jules


o cd..comando está correto e foi definido assim no intérprete de comando original command.comque mais tarde foi nomeado cmd.exe.

O interpretador de comandos sabe como processar cd.., Porque . é um personagem especial, assim como \.


19



Eu acho que a questão principal é que o comando não pode ser "sintaticamente incorreto" porque a sintaxe não é formalmente especificado em qualquer lugar, portanto, se a implementação primária (cmd.exe e / ou MS-DOS) a aceitar, ela deverá estar correta. - grawity
Além disso, o CD não é um programa, mas um comando interno. Semelhante ao Echo, que também é um comando interno, não precisa ter espaço para funcionar. echo. funciona igualmente bem, o que imprimirá uma linha vazia. - LPChip
@Overmind echoe também não funciona, então é o mesmo com cd, echo, md, etc. - LPChip
@ JonasKöritz, o . não é descartado, mas apenas um espaço é adicionado. md.test e md .test ambos criam o diretório .test. Digitando cd.test e cd .test vai mudar para o diretório .test. - daniel.neumann
@ JonasKöritz: Porque a sintaxe nunca foi argumentos de espaço de comando. - Lightness Races in Orbit


É um truque de compatibilidade com versões anteriores.

O interpretador de linha de comando é projetado para ser compatível com os comandos do interpretador de comandos original do MSDOS, que foi projetado para ser compatível com o interpretador de comandos CP / M. Nem o CP / M nem o MSDOS permitiram . em um nome de arquivo (foi interpretado como um separador entre duas partes do nome do arquivo, o nome base e a extensão). Isso significava que (pelo menos para versões anteriores do DOS), o interpretador de comandos poderia identificar se ele atingisse um '.' (ou, na verdade, qualquer outro caractere que era ilegal em um nome de arquivo) passou o final do nome do comando e estava nos argumentos do comando. Isso foi bastante comumente usado em DOS e CP / M - por exemplo, dir/w era um comando muito comum, equivalente a dir /w significado para listar arquivos em um formato horizontal.

Hoje em dia, '.' pode aparecer em nomes de arquivos. Isso causa algumas complicações na maneira de analisar comandos, mas o shell ainda identifica um . isso não faz parte de um nome de arquivo exato como sendo o começo de argumentos. Isso é necessário em grande parte porque milhões de usuários se acostumaram a digitar cd.. ou ter um grande número de arquivos em lote contendo isso ou echo. ou qualquer outro número de outros comandos semelhantes.


11