GNU утилиты для Windows


На главную

ВНИМАНИЕ
Данная статья была написана несколько лет назад и нуждается в актуализации. Оригинальный набор UnxUtils так же устарел, не поддерживается автором, а архив более недоступен на сайте разработчика. К счастью, архив UnxUtils нашелся у меня в закромах и вы можете скачать его с данного сайта.

Windows штука удобная и широкоиспользуемая, но вот средства администрирования... Разумеется, окончатые утилиты дело вкуса. Я предпочитаю всегда иметь выбор между оконным и консольным интерфесом. Большинство утилит для Windows управляются исключительно через GUI. Естественно, что это ограничивает свободу на поле автоматизации. Уверен, что я не единственный, кого не устраивают подобные ограничения. Впрочем, как и всегда есть другой путь.

Содержание:

Добавлена утилита reg.exe (отсутствует в некоторых версиях Windows). Предназначена для модификации реестра. Требуется для скрипта инсталляции.

Инсталляция

Скачайте модифицированный пакет утилит UnxUtils и сохраните архив в каком-нибудь каталоге, например "C:\UnxUtils". Утилиты намеренно не упакованы в исполняемый файл, потому что дефолтные настройки операционной системы Windows не позволяют загружать программы большого размера в режиме терминала, а исполняемый файл архива имеет размер более 3 мегабайт.

Теперь необходимо распаковать файлы. Воспользуйтесь функциями вашего файлового менеджера или распакуйте архив вручную. Во втором случае вам понадобится программа, которая сможет извлечь файлы из zip-архива. Сохраните программу unzip.exe в том же каталоге, в котором находится архив утилит (в соответствии с вышеприведенным примером это каталог "C:\UnxUtils"), после чего запустите терминал (Пуск->Выполнить->cmd) и выполните следующие команды

C:\>cd UnxUtils
C:\UnxUtils>unzip -o UnxUtils.zip
C:\UnxUtils>del unzip.exe
C:\UnxUtils>del UnxUtils.zip
Вы можете настроить окружение вручную или воспользоваться установочным скриптом
C:\UnxUtils>setup
Если вы захотите отменить сделанные установочным скриптом изменения, воспользуйтесь командой
C:\UnxUtils>setup -u
После выполнения вышеуказанной команды, можно удалить каталог, в котором располагались файлы пакета. Для получения более подробных сведений об изменениях, вносимых в систему установочным скриптом, обратитесь к праграфу Скрипт инсталляции.

Установочный скрипт

В модифицированный пакет включен shell-скрипт, который настроит операционную систему для корректной работой с утилитами. Этот скрипт расположен в корневом каталоге набора и называется "setup.bat". Ниже перечислены действия, которые выполняет даный скрипт
  • Регистрация интерпретатора shell-скриптов
  • Регистрация переменных окружения
  • Модификация переменной окружения PATH
Регистрация интерпретатора shell-скриптов

Для корректной работы программ, входящих в состав пакета, необходимо зарегистрировать определенные переменные, которые будут фигурировать в окружении при запуске терминала.

Примечание:


Переменные окружения регистрируются в ветке "HKCU", по этому вносимые изменения будут актуальны только для текущего пользователя. Изменения, касаемые переменных окружения, вносятся в ветку "HKCU\Environment".

Прежде всего, вышесказанное относится к переменной HOME. Как мы знаем, в среде UNIX переменная HOME указывает на каталог пользователя. В операционных системах Windows, путь к каталогу пользователя (или иначе - к профилю пользователя) определяет значение переменной USERPROFILE. Установочный скрипт использует это значение что бы зарегистрировать в окружении переменную HOME.

Некоторые программы используют переменную PAGER для определения программы постраничного вывода. Установочный скрипт выставляет в качестве значения переменной окружения PAGER программу "less".

Еще две переменные BISON_HAIRY и BISON_SIMPLE необходимы для корректной работы программы bison. Установочный скрипт автоматически определяет пути к файлам bison.hairy и bison.simple и регистрирует новые параметры в разделе "HKCU\Environment".

Перемнная UUT (сокр. от UNXUTILS), указывает на корневой каталог UnxUtils (т.е. каталог, в который был раскапован архив). В настоящий момент переменная UUT не используется. Регистрация этой переменной выполнена "на будущее". В дальнейшем планируется расширение набора программ дополнительными утилитами и скриптами, для работы которых может понадобится информация о корневом каталоге пакета.

Краткая справка по командам

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

zip.exe - упаковка файлов и каталогов

Программа zip позволяет упаковывать файл(ы) и/или каталог(и).

Пример создания (или обновления, в случае если архив с таким именем уже существует) архива. Команда выполняется из каталога, который подлежит архивации

D:\UnxUtils>usr\local\wbin\zip UnxUtils.zip -9r *
Выполнение вышеуказанной команды приведет к упаковке директории D:\UnxUtils включая вложенные подкаталоги и файлы. Результатом выполнения команды будет файл архива D:\UnxUtils\UnxUtils.zip, упаковка которого выполнена с максимальным (9) сжатием.

...TODO

Проблема с обратной косой чертой в путях (backslash)

Командная оболочка, входящая в состав UnxUtils, не всегда в состоянии справиться с особенностями операционной системы Windows. Чаще всего придется сталкиваться с привычкой оболочки обрабатывать эскейп-последовательности там, где это не желательно (кстати, такая же проблема обнаружена и при запуске команд под FAR-ом). Как известно, разделителем составных элементов пути в ОС Windows является символ обратного слеша '\'. Бывают ситуации, когда мы не можем работать с адаптированными для использовании в оболочке путями (т.е. с теми, где бэкслеш заменен слешем). При этом оболочка выполняет автоматическую обработку эскейп последовательностей. Согласитесь, что совсем не к месту, когда, например, мы желаем получить определенное значение реестра в переменной для последующей обработки, а бэкслеши в этом значении интерпретируются как эскейп-последовательности.

Что бы убедиться в том, что я говорю правду, давайте напишем скрипт, который продемонстрирует эту проблему. Итак, как мы мы будем присваивать определенной переменной строковое значение пути, типичного для Windows

MYVAR='D:\server\mysql\bin;D:\cygwin\usr\local\bin'
echo $MYVAR
Запустив этот скрипт, мы получим результат
D:\server\mysquin;D:ygwin\usr\locain
Ужасно! Разве мы этого ожидали? В принципе, те, кто знаком с программированием не удивятся такому результату, ведь они знают, что символ обратного слеша в строках используется как идинтификатор так называемой эскейп-последовательности - последовательности символов, которая описывает управляющий или непечатный символ. Правильно будет переписать вышенаписанный код следующим образом
MYVAR='D:\\server\\mysql\\bin;D:\\cygwin\\usr\\local\\bin'
echo $MYVAR
Для того, что бы указать в коде программы символ обратного слеша служит последовательность, состоящая из двух обратных слешей. В результате выполнения этого скрипта мы увидим совершенно корректный путь, тот самый, что и ожидали

D:\server\mysql\bin;D:\cygwin\usr\local\bin
Как видим, особых проблем с файловыми путями Windows при непосредственном определении нет. Давайте попробуем получить какой-либо путь программным способом. Пусть это будет эначение парамтра PATH в ключе реестра HKCU\Environment. Для получения значения мы будем использовать утилиту reg. Добавьте к значению этого параметра путь "D:\server\mysql\bin;D:\cygwin\usr\local\bin;", что бы можно было увидеть проблему. Если в реестре нет такого параметра, то добавьте новый параметр типа REG_SZ.

Получать значение мы будем так

reg query HKCU\Environment /v PATH
Выполните эту команду из командной строки Windows и вы увидите содержание запрошенного параметра

! REG.EXE VERSION 3.0
HKEY_CURRENT_USER\Environment
    PATH    REG_SZ  D:\server\mysql\bin;D:\cygwin\usr\local\bin
Как видим, здесь все нормально. Но давайте попробуем выполнить эту команду из скрипта командной оболочки, входящей в состав пакета UnxUtils, и присвоить результат работы некоторой переменной MYVAR
MYVAR=`reg query "HKCU\Environment" /v PATH`
echo $MYVAR
Собственно, теперь мы можем наблюдать ту самую проблему несвоевременной обработки

!REG.EXE VERSION 3.0
HKEY_CURRENT_USER\Environment
    PATH    REG_SZ  D:\server\mysquin;D:ygwin\usr\locain
Еще один вариант такой "медвежьей" услуги
echo "$USERPROFILE\\putty.rnd"
В случае если %USERPROFILE% равно например D:\Documents and Settings\root.EDEMNV.001, результатом будет такая абракадабра
oot.EDEMNV.001\putty.rnds
А все потому, что последовательность \r совершенно справедливо интерпретируется как возврат каретки. В этом случае все еще более усложняется, т.к. USERPROFILE у нас предустановлено и любая попытка использовать значение этой переменной приведет к автоматической интерполяции всех присутствующих в переменной эскейп-последовательностей.

На самом деле, все так и должно быть. Решение этой проблемы - это приемлимая плата за все те отсутствующие в Windows удобства, которые дает нам использование типичной для UNIX командной оболочки. Дело в том, что любые данные, которые попадают или выходят из окружения оболочки во время работы, интерпретируются как текстовые данные. Следовательно, любые данные, которыми манипулирует скрипт посредством переменных, обрабатываются на предмет эскейп-последовательностей. Важно уяснить, что речь идет именно о переменных, объявляемых внутри скрипта, а не о всех данных. Что бы понять разницу, в противоположность всем вышеприведенным проблемным примерам достаточно рассмотреть пример создания тарбола посредством команд tar | gzip. Данные от команды tar направляются непосредственно на вход gzip, по этому рассматриваемая нами проблема не актуальна для связки этих команд, даже в случае если эти команды находятся в одном из проблемных скриптов.

Решение довольно простое, хотя и прибавляет немного кода. Нам нужна программа, которая будет квотить возвращаемый результат. Назовем ее pquot. В принципе, мы можем использовать конструкцию вида

MYVAR=`prog arg1 arg2 | pquot`
В этом случае pquot должна будет читать STDIN, квотить бэкслеши и выводить результат на STDOUT. Но гораздо полезнее будет написать стартер, который будет выполнять команднную строку. В этом случае мы сможем добраться до проблемных перемнных окружения, правда, несколько необычным способом. Вызов команд в случае использования стартера будет выглядеть так
MYVAR=`pquot prog arg1 arg2`
Я думаю смысл понятен: стартер выполняет роль промежуточного интерпретатора, в качестве аргументов он получает командную строку, которую отправляет на выполнение дефолтному командному интерпретатору, переопределяет и читает поток вывода, эскейпит бэкслеши и в свою очередь записывает в собственный STDOUT. Таким образом, в результате присвоения, MYVAR получит корректное значение, которое можно будет использовать далее в программе.

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

MYVAR=`pquot "echo %USERPROFILE%\putty.rnd"`
echo $MYVAR
В результате мы получим строку
D:\Documents and Settings\root.EDEMNV.001
Самый элементарный стартер на perl будет выглядеть так
#!/usr/bin/perl
exit(0) unless @ARGV; 
open(PROG,"@ARGV |");
while($line = <PROG>){
    $line =~ s#\\#\\\\#g;
    print $line;
}
close(PROG);
К нему остается добавить лишь трансляцию кода завершения выполненной команды и получится полноценный стартер. С другой стороны, не хотелось бы попадать в зависимость от perl. Нет, мы его конечно любим и обязательно установим, но подразумевается что скрипты командной оболочки полноценно работают до установки какого-либо программного обеспечения, в том числе и perl. Стартер должен входить в состав UnxUtils. Его доступность должна быть гарантирована на самых начальных этапах работы нашей системы, коим и является установка пакета UnxUtils.

Наверх


Правила использования | На главную Whirlwind © 2002 - 2012

ИЯндекс цитирования