Думаю, нет смысла повторно писать вводную часть — автор оригинальной статьи это сделал до меня — и, так как моя статья вряд ли увидела бы свет, не напиши он свою, и является всего лишь альтернативным видением способа решения задачи, то я сосредоточусь на главном.
Как и автору оригинальной статьи, мне представлялось весьма странным поведение команды «cd» (или «chdir») в cmd.exe. Казалось нелогичным, что для смены активного диска необходимо каждый раз выполнять дополнительные действия. Являясь поклонником интерфейса командной строки, я не раз пробовал улучшать внешний вид и возможности стандартного командного интерпретатора Microsoft Windows, но о возможности изменить стандартное поведение команды «cd» раньше даже не задумывался. После прочтения вышеупомянутой статьи на Хабре мне не давало покоя ощущение чрезмерной нестандартности и сложности описанного способа… а желание создать свой собственный велосипед и поскорее уже начать им пользоваться привело к
Ещё одним стандартным механизмом, использующимся для настройки параметров окружения «под себя» является механизм alias -ов. Хорошо известный и часто применяемый в среде Unix подобных операционных систем, он часто оказывается обделённым вниманием и даже вообще незаслуженно позабытым в Microsoft Windows. Этот механизм позволяет назначить свои собственные имена вызова для команд, программ, пар команда/программа+параметры и, что самое главное, позволяет изменить поведение стандартных команд и программ, т.к. алиасы имеют больший приоритет по сравнению с командами оболочек и программами, найденными оболочкой в директориях, указанных в переменной окружения «PATH».
Именно этим мы и воспользуемся. Приступим!
Постановка задачи: Команда «cd» должна автоматически изменять активный диск, если в качестве аргумента передан путь к данным на отличном от текущего диске.
Решение: Казалось бы чего проще? Используя «doskey» создаём алиас «cd=cd /d $*» и радуемся жизни… но вот в чём загвоздка — ломается стандартное поведение команды «cd» при запуске без параметров. Запущенная без параметров, эта команда является полным аналогом команды «pwd» из оболочек Unix подобных операционных систем и должна бы выдавать на консоль информацию о текущей директории, но после задания алиаса она уже будет выполнятся с ключом "/d", наличие которого подразумевает и наличие следующего параметра — пути, по которому следует перейти. Не обнаружив его — команда выдаст на консоль сообщение об ошибке и завершит работу. Такое решение нас явно не устраивает!
После некоторого количества размышлений, вдумчивого просмотра страничек Хабра и активного Гугления родилось следующее решение — а почему бы не написать .bat файл? Постойте, не спешите закидывать меня помидорами, я и сам не любитель костылей. Решение было вполне продуманным и, как вы сейчас увидите, имеющим шанс оказаться рабочим.
Моя идея состояла в следующем — я решил написать .bat файл, принимающий аргументы и запускающий стандартную команду «cd» с переданными ему аргументами. В случае, если аргументов запуска у файла нет — он запускает команду «cd» без аргументов (режим вывода текущей директории), если аргументы есть — добавляет перед ними ключ "/d" и выполняет команду «cd» с ключом "/d" и переданными ему аргументами. Т.е. при использовании этого решения мы получаем желаемое — работает стандартное поведение команды «cd» без аргументов и работает автоматическая смена диска.
@echo off
if "%*" == "" (
cd
) else (
cd /d "%*"
)
exit /b
Итак, мы уже получили рабочее решение, но это ещё не то, что нам нужно. Осталось заменить стандартную команду смены директории, и в этом нам поможет механизм alias -ов. Сохраняем полученный .bat файл в одну из директорий, описанных в переменной «PATH» (к примеру в %WINDIR%\System32), с именем cd.bat и создаём алиас командой «doskey cd=cd.bat $*». Всё бы хорошо, но алиас сохранится только до закрытия текущего окна cmd.exe… надо исправить ситуацию! Создаём ещё один .bat файл для автоматической установки переменных окружения при запуске окон cmd.exe — cmd_env.bat, который так же сохраняем в выбранную директорию рядом с cd.bat
@echo off
doskey /macrofile="%USERPROFILE%\aliases"
exit /b
Также необходимо создать простой текстовый файл «aliases» и разместить его в %USERPROFILE%
cd="%WINDIR%\System32\cd.bat" $*
и .reg файл для активации автоматического запуска cmd_env.bat при открытии cmd.exe
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Command Processor]
"Autorun"="C:\\Windows\\System32\\cmd_env.bat"
Сохраняем его, к примеру, с именем cmd_env_reg.reg
Импортируем параметры из файла cmd_env_reg.reg в реестр и запускаем cmd.exe любым доступным способом. Готово! Проверяем результат!
Данное решение было успешно протестировано на работоспособность в среде Windows 2008 R2, 7, 2003 R2, XP.
PS: Большое спасибо автору оригинальной статьи за то, что подтолкнул меня к действию. Без его статьи я ещё долго терпел бы неудобства и мечтал о том, что «будет время — займусь».
PPS: Файл cmd_env.bat можно и нужно использовать для настройки cmd.exe — к примеру, для задания стандартных цветов в консоли командой «color 02» или для установки переменных окружения.
PPPS: Ссылки для интересующихся темой — ConEmu, Clink, cmder и прочие — Console2 и её форк ConsoleZ, rCons, WinQConsole
Комментарии (14)
padla2k
20.07.2015 17:43Не то что бы я очень не люблю cmd, но что вам мешает использовать powershell вместо cmd? Тем более что с 5 версии он стал вообще лапочкой и теперь еще и синтаксис команд подсвечивает. Что такого можно делать в cmd что было бы менее удобно, чем в powershell?
mutin_sa Автор
20.07.2015 18:09+1За исключением подобных описанным в статье мелочей, меня вполне устраивает cmd.exe а возможности PowerShell для моих задач избыточны и… в PowerShell не работает Far Manager. Возможно есть и другие причины, но я их сейчас не помню.
svyatogor
20.07.2015 19:53нежелания разбираться с «особенностями» cmd.exe привело меня к установке cygwin. получаем замечательно работающий шел (любой на выбор) и богатейшие возможности настройки. фар конечно не запустишь там, это конечно минус.
RumataEstora
21.07.2015 00:00+1Во-первых,
if "%*" == ""
приведет к ошибке в случае кавычек в аргументе
U:\tmp>cd /d "z:\tmp" The syntax of the command is incorrect.
Надоif "%~1" == ""
. Хотя это тоже не спасение.
Во-вторых, cd.bat — лишняя сущность. Достаточно
doskey cd=if "$*" == "" ( cd ) else ( cd /d $* )
RumataEstora
21.07.2015 00:13+2И можно расширить:
doskey cd=if "$*" == "" ( cd ) else if "$1" == "~" ( cd /d ^"^%USERPROFILE^%^" ) else ( cd /d $* )
ffwd
21.07.2015 14:59Вместо таких ухищрений, можно использовать PUSHD и POPD для навигации по папкам (доступно начиная с Win XP).
saboteur_kiev
21.07.2015 15:26Идеальное решение. Прописать алиас в реестре cd на pushd и все, теперь всегда и все работает со всеми каталогами.
mutin_sa Автор
22.07.2015 04:15У этого решения есть одна особенность — при переходе в сетевой каталог по UNC-пути, происходит автоматическое подключение сетевой папки как диска с назначением свободной буквы диска. Причём это происходит при КАЖДОМ переходе в любую сетевую папку. Автоотключения диска не происходит, т.е. очень быстро у Вас закончатся свободные буквы для дисков и вы не сможете подключить к примеру Flash-карту… а в Моём компьютере будете наблюдать кучу сетевых дисков. Как минимум, в Windows 2008 R2 это решение приводит к такому результату. На других версиях не проверял.
onix74
21.07.2015 15:36+2И после всего описанного здесь, у кого-то повернётся язык назвать линуксоида красноглазиком?! :-)
Вообще, было интересно почитать, но использовать я всё же не стану. Добавить "/d" не большая проблема. По-моему, даже меньшая, чем выполнять всё описанное на всех обслуживаемых серверах. Кроме того, подобное решение отучает от стандартного поведения стандартных команд и может доставить неудобство при работе на неподготовленных хостах. Впрочем, это всего лишь моё мнение.
Alexeyslav
21.07.2015 17:18Хм, а разве дефолтное поведение команды не может быть задано через параметры SET(переменные окружения) как это делается с командой DIR? на счет CD не знаю, но для DIR такие настройки тянутся еще с MS-DOS 6.20 по меньшей мере.
Очень жаль что такое не сделали.
saboteur_kiev
Второй батник для подгрузки алиасов писать не обязательно.
Можно просто прописать ключ
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\cd]
@=«c:\\mytools\\cd.bat»
И что примечательно, даже в PATH класть файл не обязательно. Будет работать сразу.
Фича работает начиная с win2007
Есть также ветки и для отдельных пользователей, чтобы создавать личные, а не глобальные профайлы.