25 мая 2010 г.

А что это за странные переменные окружения?

Автор: Рэймонд Чен.
Оригинал на английском: What are these strange =C: environment variables?

Вы не увидите их при выполнении команды SET, но если напишете программу, которая выводит все переменные окружения, и запустите ее в командной строке, то увидите странные переменные наподобие =C:, значения которых содержат каталоги на соответствующих дисках. Что это?

Эти переменные - часть внутренней "кухни" командного процессора cmd.exe. Именно поэтому перед этим я написал "запустите ее в командной строке": если вы запустите программу посредством диалога "Выполнить...", то не увидите их.

Ладно, командный процессор присваивает им значения, но что это? Это попытка командного процессора имитировать способ работы MS-DOS с дисками и каталогами. У Win32 есть только один текущий каталог, а в MS-DOS для каждого диска был свой текущий каталог. Рассмотрим следующую последовательность команд:

A> CD \SUBDIR
// текущий каталог диска A - A:\SUBDIR
A> B:
B> CD \TWO
// текущий каталог диска B - B:\TWO
B> A:
A> DIR
// показывает оглавление каталога A:\SUBDIR
Мы начали работать с диском A: и выбрали текущим каталогом A:\SUBDIR. Далее мы сменили диск на B: и установили в качестве текущего каталога B:\TWO. Наконец, мы вернулись к диску A: и получили оглавление каталога A:\SUBDIR, потому что это текущий каталог текущего диска.

Win32 не поддерживает концепцию отдельного текущего каталога для каждого диска, но командный процессор сохраняет поведение MS-DOS, так как люди привыкли к этому (и командные файлы рассчитывают на это). Решение заключалось в хранении "по текущему каталогу на диск" в переменных окружения со странными именами, которые бы не конфликтовали с обычными переменными окружения.

Если вы повторите вышеприведенные команды в cmd.exe, вывод будет тем же, но выполняется это другим способом.


A> CD \SUBDIR
// Переменной окружения
=A: присвоено значение A:\SUBDIR
// Текущий Win32-каталог - A:\SUBDIR
A> B:
B> CD \TWO
// Переменной окружения =B: присвоено
значение B:\TWO
// Текущий Win32-каталог - B:\TWO
B> A:
//
Текущий Win32-каталог - A:\SUBDIR

A> DIR
// показывает оглавление каталога
A:\SUBDIR


Когда мы возвращаемся на диск A:, командный процессор спрашивает:

- Так, какой каталог был текущим на диске A: в последний раз?

Он находит переменную =A:.

- О, это был каталог A:\SUBDIR.

Этот каталог и становится текущим каталогом Win32.

Но почему эти внутренние переменные хранятся в переменных окружения? Разве не могли они быть обычными переменными внутри процесса cmd.exe?

Переменные экспортируются в среду, потому что эти "текущие каталоги на каждый диск" нужны для наследования дочерними процессами. Представьте, что вы запускаете emacs из командной строки, затем из emacs выходите в другую командную строку. Вероятно, вы ожидаете, что "текущие каталоги на каждый диск" последней командной строки будут такими же, как и в предыдущей командной строке.


C:\SUBDIR> D:
D:\> emacs
M-x shell
D:\> C:
C:\SUBDIR>
// "текущий каталог диска C" сохранился, как и ожидалось

Что же делать с этими переменными?

Ничего. Просто позвольте им делать свою работу. Я рассказал о них для того, чтобы вы не волновались, когда увидите их.

Комментариев нет:

Отправить комментарий