Пятница
08-11-2024
03:41
Главная страница
Каталог статей
Информист Приветствую Вас Гость | RSS
Регистрация
Вход
Меню сайта

Категории каталога
Разное [12]
Сети [2]
Настройка и обслуживание сетей
Windows [7]

Наш опрос
Насколько вам понравился этот сайт
Всего ответов: 545

Копилка
Если вам понравился наш сайт или вы нашли полезную информацию, то у вас есть возможность отблагодарить администрацию.

Начало » Статьи » Компьютеры » Windows

Batch-файлы в Windows NT, часть 2

Мало того, если нажать кнопку Пуск, затем Справка, а потом в Справочных сведениях найти Главную страницу справочника по командам, можно узнать ещё больше интересного. Пытливый же ум может прочитать ещё и учебник по командному процессору Windows NT. Здесь же речь пойдёт о скриптах, которые облегчают жизнь лично мне. Естественно, с краткими комментариями. Итак,

Поиск фильмов в корпоративной сети

Обратите внимание, в командных файлах запрещено разбивать команду на несколько строк. В этом листинге и далее если строка начинается с пробелов, то она на самом деле является продолжением предыдущей. Сделано это с единственной целью — уместиться в окно броузера.
@echo off

ver|find "Версия" >nul
if %ERRORLEVEL%==0 set disk=Диск& goto version_found
ver|find "Version" >nul
if %ERRORLEVEL%==0 set disk=Disk& goto version_found
echo Sorry, unknown language. Bye.
goto :EOF
:version_found

for /F "tokens=1 delims= " %%m in ('net view^|find "\\"') do 
 call :invsrv %%m
goto :EOF

:invsrv
for /F "tokens=1" %%d in ('net view %1^|find "%disk%"') do
 call :invdir %1\%%d
goto :EOF

:invdir
dir /b /s "%1\*.avi" "%1\*.mpg" "%1\*.mpeg" 2>nul
goto :EOF

Мы в такие шагали дали,
Что не очень-то и дойдёшь,
Мы такие скрипты писали,
Что не очень-то и поймёшь,
Мы с почтеньем относимся к данным,
Правда, с кодом часто мудрим...
Мы охотники за экраном —
Дампом цвета ультрамарин*.

С первой строчкой всё должно быть более-менее понятно.

Вторая группа предназначена для определения версии системы — русская или английская. К сожалению, от этого зависит вывод некоторых команд, в частности, net. Команда find похожа на grep. У неё не столь широкие возможности, зато она входит в стандартную поставку. Errorlevel, в отличие от DOS, можно не только проверять на «больше или равен», но и использовать как переменную в полноценных операциях сравнения. Символ & разделяет несколько команд в строке, причём вторая выполнится независимо от того, с каким результатом завершилась первая. Есть, кроме того, разделители && и ||, которые выполняют вторую команду только при успешном/неуспешном завершении первой. Обратите внимание, что разделитель стоит вплотную к значению переменной, иначе в значение добавляется дополнительный пробел.

:EOF — это виртуальная метка, которая стоит в конце файла. Переход на неё обозначает окончание выполнения. В отличие от exit, такой способ не завершает командный интерпретатор.

Следующая группа команд представляет собой цикл по всем компьютерам сети. Мы получаем список командой net view, затем фильтруем его, чтобы выкинуть служебную информацию, а имена компьютеров оставить. Обратите внимание на символ ^ перед разделителем | — он позволяет интерпретировать всё, что написано внутри апострофов, как одну строку. Иначе этот разделитель воспринимался бы буквально, то есть разбил бы прямо посередине объемлющую команду — for.

for с ключом /f воспринимает не список значений, а поток, из которого эти значения читаются. Если название потока заключено в апострофы, как в нашем примере, то поток представляет собой стандартный вывод записанной там команды. Параметр tokens позволяет записывать в переменную цикла не целиком строку, а только первое слово из строки. Слова разделяются символами, указанными после delims.

Для каждого компьютера вызывается подпрограмма с именем invsrv. Если перед именем подпрограммы стоит двоеточие, это сигнал, что подпрограмма является не внешней программой, а меткой в текущем файле. Окончанием подпрограммы считается выполнение последней инструкции файла или, что одно и то же, переход по метке :EOF.

Дальше для каждого компьютера читается список открытых каталогов, а для каждого каталога вызывается команда dir — используются уже описанные ранее конструкции. Символ 2>nul подавляет сообщения об ошибках (поток stderr).

Говорят, что на эту тему
Наложили давно запрет,
Будто в коде нашей системы
Этих багов в помине нет,
Говорят, что в Windows 2000
Их исправили навсегда,
Только я говорю: «Дружище,
Это полная ерунда!»

Есть ли недостатки у данного скрипта? Безусловно. Например, он не будет работать для открытых каталогов, в именах которых содержится пробел. Можно исправить это, написав во втором цикле tokens=*, а вместо простого net view — маленький фильтр, например, на gawk (не забывайте, что строки на самом деле не разрываются):

net view %1 | gawk "
 /Disk/{
 l=\"\";
 for(i=1;$i!=\"Disk\";i++) l=l \" \" $i; 
 print l;
 }"

Для английской Windows это будет работать, а вот для русской — увы. Кстати, не забудьте, что все русские буквы в приведённом выше скрипте — в кодировке OEM, т.е. CP-866.

Приятного просмотра!

Архивирование модифицированных файлов

Иногда требуется создать архив, куда попали бы свежеисправленные файлы. Как правило, эта задача решается тривиально — при изменении файла у него автоматически устанавливается атрибут Archive, а потом архиватор архивирует файлы с установленным атрибутом, а сам атрибут сбрасывает. И вдруг оказалось, что InfoZip этого не умеет!

Никто не собирается спорить с тем, что Rar сжимает файлы лучше, а PkZip, возможно, понимает атрибуты. Просто для закачки, например, файлов по http на этот сайт архив обязательно должен быть zip’ом. А PkZip, что бы там ни говорили отдельные товарищи, программа коммерческая, т.е. не бесплатная.

Не стоит отчаиваться, не всё так плохо. InfoZip умеет добавлять в архив файлы, измененные не раньше определённой даты. Единственное, что надо учесть, что в России принято писать дату как ДД.ММ.ГГГГ, а в Америке — MM.DD.YYYY

Имея на руках вышеприведённые сведения, пытливый ум напишет что-нибудь вроде следующего:

@echo off
del /f site.zip >nul 2>nul
for /f "tokens=2,3,4 delims=. " %%i in ('date /t') do
 set curdate=%%j%%i%%k
zip -9Xr -t %curdate% site * -x update.cmd

и будет абсолютно прав.

Нумерация файлов в каталоге

Ещё одна задача. В каталоге имеется куча файлов, которые надо переименовать так, чтобы номера были последовательными числами. В качестве параметра скрипту будем передавать маску файлов и первый номер. Изучив вышеприведённые примеры, любой неленивый программист после некоторого раздумья напишет:

@echo off

if .%1==. goto usage

set n=%2
if .%n%==. set n=1
 
set tempdir=$tmp$.$x$
mkdir %tempdir%
for %%i in (%1) do call :renfile %%i
move %tempdir%\%1 . >nul
rmdir %tempdir%
goto :EOF

:renfile
move %1 %tempdir%\%n%%~x1 > nul
set /a n+=1
goto :EOF

:usage
echo USAGE RENUMBER *.HTM ^<first number^>

Потом, правда, возникнет вопрос, нельзя ли вместо вызова подпрограммы renfile сразу через амперсанд написать требуемые команды. Но, подумав или попробовав, можно убедиться, что нельзя, т.к. неправильно будет работать set. Дело в том, что подстановка значения переменной происходит до, а не во время выполнения цикла, т.е. сначала вычислится %tempdir%\%n%%~x1, а потом уже все файлы будут перемещаться по одному и тому же адресу.

Правда, можно сделать и так, чтобы значения переменных подставлялись при каждой итерации цикла. Для этого надо заключить переменную не в проценты, а в восклицательные знаки, то есть написать %tempdir%\!n!%~x1. А потом ещё разрешить такую обработку переменных, запустив командный процессор с ключом /V:ON. Можно и разрешить такую обработку по умолчанию, записав 1 по одному из следующих адресов в реестре (для одного пользователя и для всех пользователей соответственно):

HKCU\Software\Microsoft\Command Processor\DelayedExpansion
HKLM\Software\Microsoft\Command Processor\DelayedExpansion

Кстати, вот ещё одна нехитрая команда, которая позволит узнать больше о внутреннем мире вашего компьютера:

cmd /?

Злые баги не остановишь,
Просто знайте: blue screen of death
То ли Гейтс, то ли Руссинович
Перекрасили в чёрный цвет
И пришлось им забраться глубже —
Прямо в код самого ядра...
Чтоб поймать их, работать нужно
Просто с вечера до утра.

Из особенностей кода хотелось бы отметить присваивание с вычислением (set /a) и выделение из полного имени файла расширения (конструкция %~x1). Подробнее о подобных конструкциях см. call /?. Ну, и разумеется, птички перед символами < и >, позволяющие не воспринимать их как команды перенаправления ввода/вывода.

Узнать длину файла

Задача сформулирована предельно просто. Проигнорировать файл, если его не существует или он нулевой длины (или ненулевой). Тот, кто детально разобрался с инструкцией for, радостно воскликнет: «Давайте напишем подпрограмму, вычисляющую её! Например, вот так...»

:list_file
for /f "tokens=3" %%i in ('dir /-C %1^|find "%1"') do 
 set FILELEN=%%i
goto :EOF

Нельзя не согласиться с товарищем, если ничего, кроме Windows NT 4 он не видел. Но настоящий программист, у которого под рукой Windows 2000 и которого данная статья побудила RTFM, поступит так:

:list_file
set FILELEN=%~z1
goto :EOF

Выводы

Командный язык Windows NT — всё ещё корявый и хитрый, но уже достаточно мощный инструмент, которым можно и нужно пользоваться в повседневной жизни. Успехов вам, товарищи!



Источник: http://hardsign.hardsign.com/prog/2
Категория: Windows | Добавил: Judge (15-11-2009)
Просмотров: 2180 | Рейтинг: 0.0 |

Всего комментариев: 0
Имя *:
Email *:
Код *:
Форма входа

Поиск по каталогу
Яндекс


Поиск по Информисту

Наша кнопка


Друзья сайта

Статистика


Copyright MyCorp © 2006Сайт создан в системе uCoz