Ao digitar cd..
sem um espaço entre cd
e ..
prompt de comando do Windows irá alegremente mudar para a pasta pai. Existe uma explicação para esse comportamento? O comando não segue o formato padrão decommand<space>arguments
Além disso, por que isso não cria resultados consistentes?
windows
command-line
command-line-arguments
Jonas Köritz
fonte
fonte
dir/a
ou a sintaxe semelhante do VMS.cd c:\program files
sem aspas e ainda funcionacd..
funciona? Porque a Microsoft enfrentou o problema de explicitamente fazê-lo funcionar.cd
é um comando incorporado ao interpretador de comandos do Windows e a Microsoft pode fazer com que o intérprete faça o que quiser. (Como outro exemplo,cd
também não precisa citar torno de diretórios com espaços no nome.)Respostas:
Como algumas das outras respostas / comentários observam, a idéia de que deve haver um espaço após o comando não está correta. Um exemplo conhecido é que você pode digitar uma barra após um comando, sem precisar primeiro de um espaço.
No entanto, existe outro comportamento que é um pouco menos compreendido e permite o "
cd..
" que você está perguntando. Esse comportamento também permite que "cd\
" funcione.O comportamento que você descreve é consistente para todos os comandos internos ao interpretador de linha de comando. Se você tiver determinados símbolos, incluindo um ponto final, barra invertida ou barra invertida, os caracteres anteriores serão verificados para ver se 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 ocopy
comando, portanto os resultados são inconsistentes: eles não são necessariamente os mesmos com todos os comandos internos. Eu não continuei minha pesquisa para comparar (muito) outras linhas de comandodel
edir
, por isso, sugiro ser extremamente cuidadoso se você tentar confiar no que acontece sem um espaço.Agora, a pergunta também foi feita sobre o comando echo : Esta é uma exceção incomum, pois acho que
echo.
é bastante conhecida pelos especialistas do DOS. Provavelmente isso foi documentado. O comportamento, pelo menos no CMD do Win7 , é que, se o comando iniciar com "echo.
", o primeiro período será ignorado. Então, "echo..hi
" se transforma na saída de ".hi
". A razão para isso é "echo.
" que pode ser usada para imprimir uma linha em branco. Por outro lado, com o Unix, você pode fazer isso simplesmente executando o "echo
" comando por si só. No entanto, no DOS, executar oecho
comando " " por si só produzirá a configuração " eco " atual . 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 suficientemente recentes do interpretador de linha de comando CMD da Microsoft .)Portanto, pelo menos o
echo
comando tem uma explicação semi-razoável. Quanto aos comandos restantes, eu costumava pensar que os comandos internos tinham prioridade. No entanto, quando tentei fazer alguns testes, descobri que isso é realmente inconsistente. Demonstro isso através de alguns exemplos que documentamos aqui.Aqui estão alguns exemplos. Eu usei um prompt de comando elevado, para que o UAC não se queixasse de mim escrevendo no diretório raiz. Isso foi feito com o CMD.EXE do Microsoft Windows 7. Suspeito que os comportamentos possam ser diferentes com outras versões, como o COMMAND.COM de versões anteriores do MS-DOS ou com o software lançado por outras empresas (COMMAND.COM do DR-DOS).
(Essa resposta já é bastante longa, então não incluo comandos para limpar toda a bagunça que fiz no meu sistema de arquivos. Há um pouquinho de limpeza, mas não muita.)
Aqui está um exemplo que prova que o comando interno cria precedência. (Também demonstro a capacidade pouco conhecida de usar dois pontos duplos para efetivamente ser um comentário, o que também funciona bem em arquivos em lote. 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.)
Aqui está um exemplo de demonstração de cópia , com um caminho completo, não usa a mesma precedência (favorecendo o comando interno) que o cd quando nenhuma extensão é usada:
Minhas descobertas iniciais indicaram que esses resultados demonstram que o shell da linha de comando dá prioridade:
Isso demonstra claramente que o comportamento não é consistente entre o comando copy (com um nome de arquivo completo incluindo uma extensão) e o comando cd (sem uma extensão como parte do nome do diretório). Ao usar uma barra invertida, o comando copy (com a extensão completa do nome do arquivo) verificará primeiro o sistema de arquivos, mas o comando cd não (se o diretório não contiver uma extensão).
(Atualização: no começo, achei que a inconsistência se baseava em comportamentos diferentes entre os programas. Mais tarde, descobri que a inconsistência existia, mas foi causada mais pelos parâmetros fornecidos.)
Na verdade, mesmo esses pontos não são totalmente precisos, mesmo que eu pareça demonstrar todas as coisas que acabei de dizer. O problema é que essa lista de pontos de bala não é precisa o suficiente para ser completamente precisa. (Deixei as coisas imprecisas para que esses itens pudessem ser comparados com relativa facilidade e verificados com relativa facilidade.)
No entanto, para ser mais preciso, o primeiro ponto deve apontar que o shell da linha de comando dá prioridade:
A seguir, demonstrarei por que estou fazendo essa distinção:
(Observe que o último comando de cópia procurou o arquivo chamado \ needext , porque o comando de cópia interno foi usado. O arquivo \ needext.bat foi criado apenas para ajudar a mostrar com facilidade que nunca foi usado pelas linhas de comando que incluíam a palavra cópia .)
Neste ponto, eu estabeleci alguma inconsistência (com o comportamento do comando copy ) quando uma barra invertida é usada ...
A seguir, demonstrarei que há alguma consistência entre esses comandos. (Portanto, há consistência ... um ... às vezes. Podemos ter apenas consistência, inconsistentemente.) O que mostrarei a seguir é que o comando cd se comporta como o comando copy quando um ponto é usado. O comando copy usa o comando interno e o comando cd .
Portanto, durante a sessão de teste inicial, focada principalmente nos comandos cd e copy (com algum uso adicional de md e um pouco de del ), a única vez em que realmente tivemos o sistema de arquivos com prioridade foi com o comando copy , e então o comando copy O sistema de arquivos estava apenas tendo prioridade ao usar o caminho completo.
Após uma revisão subsequente, descobri que o comando cd também dava prioridade ao sistema de arquivos ao usar uma extensão. Pelo menos isso significa que os comandos internos estão sendo tratados um pouco mais consistentes entre si. No entanto, isso também significa que temos um comportamento diferente com base nos nomes dos objetos do sistema de arquivos (os arquivos ou diretórios). Parece que o comportamento está usando alguma lógica interna muito, muito obscura. Portanto, contar com esse comportamento para funcionar em diferentes sistemas operacionais é algo que eu provavelmente consideraria inseguro .
fonte
ipconfig
por exemplo, também funciona.IPCONFIG/ALL
. No entanto, não era disso que eu estava falando. " O comportamento que você descreve " (na sua pergunta) era o comportamento de colocar um ponto logo após o nome do comando. Se eu digitarIPConfig.
, 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 digitarIPCONFIG\ALL
, posso executar um.\IPCONFIG\ALL.BAT
arquivo personalizado que criei. Portanto/
, não são tratados como.
ou `\`copy.exe
oucopy.com
no cmd. Não funciona - não é um executável.ipconfig
, discordo de sua conclusão. Esta pergunta é sobre o que é digitado no início de uma linha de comando. O Windows / DOS identifica os 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, diferente do Unix que permite isso). Quanto ao próximo comentário, não sei quem é "Calchas". (Quando você especifica um sinal de arroba, geralmente são os primeiros caracteres de um usuário que aparece em outro lugar da página.) Concordo que a execução "copy.exe
" utilizará ocopy
comando interno (e pass.exe
). (Você pode executar.\copy.exe
)Você assume que um nome de comando e seus argumentos devem ser separados por um espaço, especificamente, mas isso não é verdade. Desde que a chamada possa ser interpretada sem ambiguidade, a chamada é válida.
Neste caso, o primeiro argumento começa com
.
e.
não pode ser parte do nome do comando, entãocd
e..
são simplesmente analisado como dois tokens separados.Geralmente, seu primeiro argumento começa com um caractere alfabético (por exemplo, o início de um caminho), portanto, ele "sangra" no nome do seu comando e causa um erro ... mas isso não é um problema de sintaxe. É semântico.
Você pode ver o mesmo efeito trabalhando com outros comandos, incluindo
echo
:Nesse caso, obtemos apenas dois períodos porque o
echo
próprio comando possui uma regra especial , de modo que o seguinte:ou, por extensão, esta:
gera apenas uma linha vazia. É uma conveniência. Aparentemente, isso foi implementado ignorando um período inicial no argumento.
Ei, isso é DOS / lote. Você quer sanidade? : D
fonte
cd..
cd..
seja :)alias cd..='cd ..'
.
e..
que aparece como diretórios em todos os outros diretórios e, até onde eu sei, nunca pretendia captar mais do que isso. Na verdade, eu considero o oculto modelado como atributo de arquivo um design mais limpo do que ter implícito o nome do arquivo..
nomes de arquivos , o que significava que não poderia fazer parte do nome de um comando, portanto, deve ter sido parte do argumento . Mesmo se o DOS tivesse dividido o comando em argumentos, como os shells do Unix, ainda assim colocaria um.
após o comando no primeiro argumento, porque não faria sentido colocar um caractere inválido no nome do comando.O
cd..
comando está correto e foi definido assim no intérprete de comando originalcommand.com
que mais tarde foi nomeadocmd.exe
.O intérprete de comando sabe como processar
cd..
, porque.
é um caractere especial, assim como\
.fonte
echo.
funciona da mesma maneira, o que imprimirá uma linha vazia..
não é descartado, mas apenas um espaço é adicionado.md.test
emd .test
tanto criar o diretório.test
. Digitandocd.test
ecd .test
vai mudar para o diretório.test
.É um hack de compatibilidade com versões anteriores.
O interpretador de linha de comando foi 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 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 comando poderia identificar isso se atingisse um '.' (ou qualquer outro caractere ilegal em um nome de arquivo) passou o final do nome do comando e entrou nos argumentos do comando. Isso era comumente usado no DOS e no CP / M - por exemplo,dir/w
era um comando muito comum, equivalente aodir /w
significado de listar arquivos em um formato horizontal.Hoje em dia, '.' pode aparecer nos nomes de arquivos. Isso causa algumas complicações em como analisar comandos, mas o shell ainda identifica um
.
que não faz parte de um nome de arquivo exato como sendo o início dos argumentos. Isso é necessário em grande parte porque milhões de usuários se acostumaram a digitarcd..
ou possuem um grande número de arquivos em lote contendo esseecho.
ou qualquer outro número de comandos semelhantes.fonte