При наборе текста cd..
без пробела между cd
и ..
командная строка Windows с радостью переключится в родительскую папку. Есть ли объяснение этому поведению? Команда не соответствует стандартному форматуcommand<space>arguments
Кроме того, почему это не создает последовательных результатов?
windows
command-line
command-line-arguments
Йонас Кёриц
источник
источник
dir/a
или похожий синтаксис VMS.cd c:\program files
без кавычек, и это все еще работаетcd..
работает? Потому что Microsoft столкнулась с проблемой явно заставить его работать.cd
это команда, встроенная в интерпретатор команд Windows, и Microsoft может заставить их интерпретатор делать что угодно. (В качестве другого примера,cd
также не нужноОтветы:
Как отмечают некоторые другие ответы / комментарии, идея о том, что после команды должен быть пробел, неверна. Хорошо известным примером является то, что вы можете вводить косую черту после команды, не используя пробел.
Тем не менее, есть другое поведение, которое немного менее понятно, и допускает "
cd..
", о котором вы спрашиваете. Такое поведение также позволяет "cd\
" работать.Поведение, которое вы описываете, является совместимым для всех команд, встроенных в интерпретатор командной строки. Если у вас есть определенные символы, включая точку, косую черту или обратную косую черту, то проверяются предыдущие символы, чтобы определить, являются ли они командой, которая является внутренней для оболочки «интерпретатора командной строки» (CMD.EXE или его предшественника COMMAND.COM ).
Это может быть сделано перед проверкой, может ли слово относиться к файлу или подкаталогу. Это верно для
cd
команды. К сожалению, при создании образца я обнаружил, что сcopy
командой этого не происходит , поэтому результаты не всегда совпадают: они не обязательно совпадают со всеми внутренними командами. Я не продолжил свой поиск, чтобы также сравнить (много) другие командные строки,del
иdir
поэтому я просто предлагаю быть предельно осторожным, если вы пытаетесь полагаться на то, что происходит без пробела.Теперь также задан вопрос о команде echo : это необычное исключение, которое, я думаю
echo.
, довольно хорошо известно специалистам DOS. Это, вероятно, было задокументировано. Поведение, по крайней мере, в CMD Win7 , заключается в том, что если команда начинается с "echo.
", то первый период игнорируется. Таким образом, "echo..hi
" превращается в вывод ".hi
". Причина этого в том, что «echo.
» можно использовать для печати пустой строки. В отличие от Unix, вы можете сделать это, просто запустив команду "echo
". Тем не менее, в DOS, выполнение команды "echo
" само по себе выведет текущую настройку " эхо ". Точно так же DOS рассматривает "Echo *Off*
" и "Echo *On*
"как специальные значения, которые изменяют текущую настройку эха. Если вы действительно хотите напечатать слово"Off
", то"Echo.Off
"добьется цели (по крайней мере, с достаточно недавними версиями интерпретатора командной строки CMD от Microsoft .)Так что, по крайней мере, у
echo
команды есть полуразумное объяснение. Что касается остальных команд, я привык думать, что внутренние команды имеют приоритет. Однако, когда я попытался сделать несколько тестов, я обнаружил, что это довольно противоречиво. Я демонстрирую это на нескольких примерах, которые я задокументировал здесь.Вот несколько примеров. Я использовал командную строку с повышенными правами, чтобы UAC не обращал на меня внимание при записи в корневой каталог. Это было сделано с помощью Microsoft Windows 7 CMD.EXE. Я подозреваю, что поведение может отличаться в других версиях, таких как COMMAND.COM из более старых версий MS-DOS или программного обеспечения, выпущенного другими компаниями (DR-DOS's COMMAND.COM).
(Этот ответ уже довольно длинный, поэтому я не включаю команды, чтобы очистить весь беспорядок, который я сделал в моей файловой системе. Есть небольшая часть очистки, но не очень.)
Вот пример, который доказывает, что внутренняя команда создает приоритет. (Я также демонстрирую довольно малоизвестную способность использовать двойное двоеточие, чтобы эффективно быть комментарием, который также хорошо работает в пакетных файлах. Технически, в пакетных файлах, он обрабатывается как метка, которая не может быть достигнута GOTO, и заканчивается быть быстрее, чем команда REM.)
Вот пример, демонстрирующий, что копия с полным путем не использует тот же приоритет (в пользу внутренней команды), что и cd, когда расширение не используется:
Мои ранние результаты показали, что эти результаты показывают, что командная строка дает приоритет:
Это ясно демонстрирует, что поведение не согласовано между командой copy (с полным именем файла, включая расширение) и командой cd (без расширения как части имени каталога). При использовании обратной косой черты команда copy (с полным расширением имени файла) сначала проверит файловую систему, а команда cd - нет (если каталог не содержит расширения).
(Обновление: сначала я думал, что несоответствие было основано на различном поведении между программами. Позже я обнаружил, что несоответствие действительно существовало, но было вызвано больше из предоставленных параметров.)
На самом деле, даже эти пункты не совсем точны, хотя я, кажется, только что продемонстрировал каждую отдельную вещь, которую я только что сказал. Проблема в том, что список пунктов не достаточно точен, чтобы быть полностью точным. (Я оставил вещи неточными, чтобы можно было сравнительно легко сравнивать эти пункты и проверять их относительно легко.)
Тем не менее, чтобы быть более точным, первый пункт должен указать, что оболочка командной строки дает приоритет:
Следующее покажет, почему я делаю это различие:
(Обратите внимание, что последняя команда копирования искала файл с именем \ needext , поскольку использовалась внутренняя команда копирования . Файл \ needext.bat был создан только для того, чтобы легко показать, что он никогда не использовался командными строками, включающими слово copy .)
На этом этапе я установил некоторую несогласованность (с поведением команды копирования ), когда используется обратный слеш ...
Далее я продемонстрирую, что между этими командами есть некоторая согласованность. (Итак, есть последовательность ... хм ... иногда. У нас может быть только непротиворечивость, непоследовательность.) Далее я покажу, что команда cd ведет себя скорее как команда копирования, когда используется точка. Команда copy использует внутреннюю команду, как и команда cd .
Итак, во время начального сеанса тестирования, который в основном был сосредоточен на командах cd и copy (с некоторым дополнительным использованием md и немного del ), единственный раз, когда у нас действительно была приоритетность файловой системы, была команда copy , а затем файловая система имела приоритет только при использовании полного пути.
После последующего просмотра я обнаружил, что команда cd также отдает приоритет файловой системе при использовании расширения. По крайней мере, это означает, что внутренние команды обрабатываются немного более согласованно друг с другом. Однако это также означает, что мы получаем другое поведение в зависимости от имен объектов файловой системы (файлов или каталогов). Кажется, что в поведении используется какая-то действительно очень непонятная внутренняя логика. Поэтому, полагаясь на такое поведение для работы в разных операционных системах, я бы посчитал это небезопасным .
источник
ipconfig
например тоже работает.IPCONFIG/ALL
. Однако это не то, о чем я говорил. « Поведение, которое вы описываете » (в вашем вопросе), было поведением точки после имени команды. Если я печатаю,IPConfig.
я получаю сообщение об ошибке, что команда не найдена. Точно так же (хотя это не относится к описанному вами поведению), если я наберуIPCONFIG\ALL
текст, я могу запустить.\IPCONFIG\ALL.BAT
созданный мной файл. Так/
что не обращаются как.
или `\`copy.exe
илиcopy.com
в cmd. Это не работает - это не исполняемый файл.ipconfig
, я не согласен с вашим выводом. Этот вопрос о том, что напечатано в начале командной строки. Windows / DOS идентифицирует исполняемые файлы по расширению имени файла, поэтому вы не можете запустить программу под названием «ipconfig» без расширения (в Windows, в отличие от Unix, который разрешает это). Что касается следующего комментария, я не знаю, кто такой "Calchas". (Когда вы указываете знак «at», обычно это следующие первые символы пользователя, который появляется в другом месте на странице.) Я согласен, при запуске «copy.exe
» будет использоваться внутренняяcopy
команда (и pass.exe
). (Вы можете бежать.\copy.exe
)Предполагается, что имя команды и ее аргументы должны быть разделены пробелом, но это не так. Пока вызов может быть однозначно интерпретирован, вызов действителен.
В этом случае, первый аргумент начинается с
.
и.
не может быть частью имени команды, такcd
и..
просто обрабатывается как два отдельных лексем.Обычно ваш первый аргумент начинается с буквенного символа (например, с начала пути), поэтому он «сливается» с именем вашей команды и вызывает ошибку… но это не проблема синтаксиса. Это семантический.
Вы можете увидеть тот же эффект при работе с другими командами, в том числе
echo
:В этом случае мы получаем только два периода, потому что у
echo
самой команды есть специальное правило , так что следующее:или, по сути, это:
выводит только пустую строку. Это удобство. По-видимому, это было реализовано путем игнорирования начального периода в аргументе.
Привет, это DOS / Batch. Вы хотите здравомыслие? : D
источник
cd..
cd..
:)alias cd..='cd ..'
.
и..
которые отображаются в виде каталогов в любой другой директории , и, насколько я знаю , никогда не был предназначен , чтобы поймать больше , чем это. Я на самом деле считаю скрытность, смоделированную как атрибут файла, более чистой конструкцией, чем то, что она неявно вытекает из имени файла..
имен файлов , что означало, что он не мог быть частью имени команды, поэтому должен был быть частью аргумента . Даже если бы DOS разделил команду на аргументы, как это делают оболочки Unix, он все равно.
поместил бы после команды в первый аргумент, потому что не было бы смысла вставлять недопустимый символ в имя команды.Команда
cd..
верна, и она была определена так же, как и в оригинальном интерпретаторе команд,command.com
который впоследствии был названcmd.exe
.Интерпретатор команд знает, как обрабатывать
cd..
, потому что.
это специальный символ, как и\
.источник
echo.
работает так же хорошо, что будет печатать пустую строку..
не опускается, а просто добавляется пробел.md.test
иmd .test
оба создают каталог.test
. Набравcd.test
иcd .test
изменится в каталог.test
.Это взлом обратной совместимости.
Интерпретатор командной строки предназначен для обратной совместимости с командами исходного интерпретатора команд MSDOS, который был разработан для обратной совместимости с интерпретатором команд CP / M. Ни CP / M, ни MSDOS не допускали использование a
.
в имени файла (это интерпретировалось как разделитель между двумя частями имени файла, базовым именем и расширением). Это означало, что (по крайней мере, для ранних версий DOS) интерпретатор команд мог определить это, если достигнет «.» (или любой другой символ, который был недопустим в имени файла), он прошел конец имени команды и был в аргументах команды. Это довольно часто использовалось как в DOS, так и в CP / M - например, этоdir/w
была очень распространенная команда, эквивалентнаяdir /w
значению перечислять файлы в горизонтальном формате.В наше время, '.' может появиться в именах файлов. Это вызывает некоторые сложности в том, как анализировать команды, но оболочка все еще идентифицирует,
.
что не является частью точного имени файла, как начало аргументов. Это необходимо в значительной степени потому, что миллионы пользователей привыкли печататьcd..
или имеют большое количество командных файлов, содержащих этуecho.
или любую другую аналогичную команду.источник