Bat формат даты

Система Orphus


RSDN Magazine #2-2005

Что это за упомянутые ранее операторы объединения команд?

 command1 & command2
command1 && command2
command1 || command2 

Форма этих операторов весьма соответствует их содержанию. В случае, пожалуй, наименее полезного оператора & вторая команда будет просто выполнена после первой, т.е. это равносильно простой записи:

Оператор && гарантирует, что вторая команда будет выполнена только, если первая была выполнена успешно, т.е. с нулевым кодом возврата (он же %errorlevel%). Такие конструкции очень популярны в мире shell-сценариев Unix. Например:

Если перейти в каталог sources не удастся, то будет произведен выход с кодом ошибки 1. Если же первая команда отработает нормально, то вторая выполнена не будет. Например, такая простейшая защита помогла бы в случае с cd по UNC-адресу, описанному ранее.

Введение

Мы все любим писать серьезные вещи на серьезных языках. Шаблоны, C++, Reflection, Perl и многое другое – вот то, что мы любим, то, чему посвящаем длинные сообщения в форумах, то, что снится нам по ночам.

К чему я это все? А к тому, что поговорим мы о полезных хитростях при написании файлов сценариев на встроенном командном языке Windows. К счастью, это занятие не является доминирующим в профессиональной деятельности автора, так что я не обязуюсь заполнить абсолютно все пробелы в данной области. Кроме того, рожденный ползать летать не может, и из cmd.exe, увы, не получится ни /usr/bin/perl, ни даже /bin/sh. Так что, все нижеприведенное – просто некоторые интересные факты из жизни файлов с расширением bat, на которые автор обратил внимание во время решения различных практических задач автоматизации.

ПРЕДУПРЕЖДЕНИЕ

Сеанс по времени, зависящий от региона,

Выходной формат %DATE%
и команды dir
зависит от региона и, следовательно, не является ни надежным, ни умным. date.exe
(часть UnxUtils
) предоставляет любые дату и время в любом воображаемом формате. Вы также можете извлечь информацию о дате/времени из любого файла с помощью date.exe
.

Примеры: (в cmd- script используйте %% вместо%)

date.exe +"%Y-%m-%d"

2009-12-22

date.exe +"%T"

18:55:03

date.exe +"%Y%m%d %H%M%S: Any text"

20091222 185503: Любой текст

date.exe +"Text: %y/%m/%d-any text-%H.%M"

Текст: 09/12/22 – любой текст-18.55

Command: date.exe +"%m-%d """%H %M %S """"

07-22 “18:55:03” `

Информация о дате/времени из справочного файла:

date.exe -r c:\file.txt +"The timestamp of file.txt is: %Y-%m-%d %H:%M:%S"

Используя его в CMD script, чтобы получить информацию о год, месяц, день, время:

 for /f "tokens=1,2,3,4,5,6* delims=," %%i in ('C:\Tools\etc\date.exe +"%%y,%%m,%%d,%%H,%%M,%%S"') do set yy=%%i& set mo=%%j& set dd=%%k& set hh=%%l& set mm=%%m& set ss=%%n 

Используя его в CMD script, чтобы получить отметку времени в любом требуемом формате:

 for /f "tokens=*" %%i in ('C:\Tools\etc\date.exe +"%%y-%%m-%%d %%H:%%M:%%S"') do set timestamp=%%i 

Извлечение информации о дате/времени из любого ссылочного файла.

 for /f "tokens=1,2,3,4,5,6* delims=," %%i in ('C:\Tools\etc\date.exe -r file.txt +"%%y,%%m,%%d,%%H,%%M,%%S"') do set yy=%%i& set mo=%%j& set dd=%%k& set hh=%%l& set mm=%%m& set ss=%%n 

Добавление в файл информации о дате/времени:

 for /f "tokens=*" %%i in ('C:\Tools\etc\date.exe -r file.txt +"%%y-%%m-%%d.%%H%%M%%S"') do ren file.txt file.%%i.txt 

date.exe часть бесплатных инструментов GNU
, которые не требуют установки.

ПРИМЕЧАНИЕ. Копирование date.exe
в любой каталог, находящийся в пути поиска, может привести к сбою других сценариев, которые используют встроенную команду date
для Windows.

Народная мудрось

всем все никому ничего(с).

 @echo off
set day=%DATE:~0,2%
set month=%DATE:~3,2%
set year=%DATE:~6,4%
set hour=%TIME:~0,2%
set minute=%TIME:~3,2%
set second=%TIME:~6,2%
echo %day%
echo %month%
echo %year%
echo %hour%
echo %minute%
echo %second%
set YYYYMMDD=%year%%month%%day%
echo %YYYYMMDD% 

Igor Polyakov igorpol_gbt (at) mail (dot) ru

Posted via RSDN NNTP Server 1.9

 gbt>@echo off
gbt>set day=%DATE:~0,2%
gbt>set month=%DATE:~3,2%
gbt>set year=%DATE:~6,4%
gbt>set hour=%TIME:~0,2%
gbt>set minute=%TIME:~3,2%
gbt>set second=%TIME:~6,2%
gbt>echo %day%
gbt>echo %month%
gbt>echo %year%
gbt>echo %hour%
gbt>echo %minute%
gbt>echo %second%
gbt>set YYYYMMDD=%year%%month%%day%
gbt>echo %YYYYMMDD%
gbt> 

gbt> Igor Polyakov igorpol_gbt (at) mail (dot) ru

Сейчас так и сделано, но есть проблеммы, из за того, что локаль то у всех разная, по этому вырезать низя Bat формат даты

Народная мудрось

всем все никому ничего(с).

 %TIME%Returns the current time. Uses the same format as the time /t command. Generated by Cmd.exe.
For more information about the time command, see Time. 
 TimeChanging the time formatYou can change the time format by changing the setting in Date and Time in Control Panel.
For just the MS-DOS subsystem, change the country setting in your Config.nt file.
Depending on the Country/Region selected, time is displayed in the 12-hour format or the
24-hour format. If you are setting the time in the 12-hour format, specify P for hours after noon. 

Так что, похоже переносимо никак. Либо написать свою утилиту, которую вызывать в

cmd’шнике.

Igor Polyakov igorpol_gbt (at) mail (dot) ru

Posted via RSDN NNTP Server 1.9

http://gzip.rsdn.ru/Forum/Message.aspx?mid=938074

Похоже WSH — единственное надежное средство.

W>Похоже WSH — единственное надежное средство.

Да, похоже на то

Народная мудрось

всем все никому ничего(с).

Как можно избежать использования goto?

Любой хоть сколько-то осмысленный *.bat-файл длиной больше 50 строк является ярким лозунгом в поддержку работы Дейкстры «О вреде оператора goto»
. Мешанина из переходов вперед и назад действительно является кодом «только для записи». Можно ли что-то предпринять по этому поводу?

На самом деле можно. Как правило, большинство меток и переходов используются для организации ветвлений при проверке условий, т.е. банальных if-then-else блоков. В оригинале, bat-язык поддерживал только одну команду в блоке then, что автоматически приводило к идиомам вида:

 condition :THEN
IF_END
:THEN
:IF_END 

Но к счастью, командный интерпретатор cmd.exe современных ОС Windows 2000 и старше поддерживает блоки команд в конструкциях ветвления, что устраняет необходимость применения меток. Блоки команд заключаются в круглые скобки. Выглядит это так (имитируя C/C++ indentation style):

 condition ( ) ( ) 

Конкретный пример использования:

 off BUILDMODE=%1
"%BUILDMODE%" == (  FAIL: Аргумент является обязательным ^(--debug, --release^)  /b 1
) BUILDMODE=%BUILDMODE:-=% "%BUILDMODE%" == "debug" (  INFO: Устанавливаем debug-режим окружения  CCFLAGS=/Od /MDd /Z7
) (  INFO: Устанавливаем release-режим окружения  CCFLAGS=/O2 /MD
) 

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

 "%BUILDMODE%" == (  INFO: Устанавливаем debug-режим окружения  OPTFLAGS=/Od CCFLAGS=%OPTFLAGS% /MDd /Z7
) (  INFO: Устанавливаем release-режим окружения  OPTFLAGS=/O2 CCFLAGS=%OPTFLAGS% /MD
) 

Загвоздка в том, что в обоих блоках подстановка переменной OPTFLAGS произойдет до того, как она будет изменена в процессе выполнения этого блока. Соответственно, в CCFLAGS будет подставлено то значение, которое OPTFLAGS имела на момент начала выполнения данного if-блока.

 enabledelayedexpansion 

в тексте самого bat-файла. Второй способ мне представляется более удобным – не очень здорово требовать от кого-то запуска твоего сценария с определенным параметром.

:/>  Как подключиться к ssh при помощи стандартной командной строки windows

С учетом сказанного предыдущий «неправильный» пример может быть исправлен так:

 enabledelayedexpansion "%BUILDMODE%" == (  INFO: Setting up debug mode environment  OPTFLAGS=/Od CCFLAGS=!OPTFLAGS! /MDd /Z7
) (  INFO: Setting up release mode environment  OPTFLAGS=/O2 CCFLAGS=!OPTFLAGS! /MD
) 

Но в любом случае, это гораздо лучше безумного количества меток и переходов.

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

Иногда сценарию надо знать полный путь к себе самому и/или к каталогу, в котором он находится. Это может понадобиться по разным причинам. Например, он должен достать из системы контроля версий исходники в каталог <script-dir>/src рядом с собой. Или, запускаются тесты из каталога <script-dir>/tests, и перед их запуском надо добавить каталог <script-dir>/bin в переменную PATH.

Можно, конечно, рассчитывать на то, что командный файл был вызван из того же каталога, где он находится, и тогда в качестве вышеупомянутого <script-dir> можно использовать переменную окружения %CD% – полный путь к текущему каталогу. Однако любые допущения в нашем деле недопустимы (хороший каламбур, однако!). Поэтому приведу более надежное решение.

Прежде всего, вспоминаем, что переменная %0 в bat-файле соответствует нулевому аргументу командной строки, т.е. имени самого файла. После этого читаем скудную документацию для команды call:

и обнаруживаем, что при использовании нумерованных переменных %0-%9 можно использовать некоторые модификаторы:

 %~1 - разворачивает %1, удаляя кавычки (") %~f1 - разворачивает %1 в полный квалифицированный путь %~d1 - разворачивает %1 в букву диска %~p1 - разворачивает %1 в путь %~n1 - разворачивает %1 в имя файла %~x1 - разворачивает %1 в расширение файла %~s1 - развернутый путь будет содержать только короткие имена %~a1 - разворачивает %1 в атрибуты файла %~t1 - разворачивает %1 в дату/время создания файла %~z1 - разворачивает %1 в размер файла %~$PATH:1 - Ищет в каталогах, перечисленных в переменной среды PATH, и разворачивает %1 в полное квалифицированное имя первого совпадения. Если имя перменной среды не определено, или если файл не найден, этот модификатор вернет пустую строку 

и, более того:

 Модификаторы можно объединять для получения сложных результатов: %~dp1 - разворачивает %1 в букву диска и путь %~nx1 - разворачивает %1 в имя файла с расширением %~dp$PATH:1 – ищет %1 в каталогах, перечисленных в переменной среды PATH, и разворачивает в букву диска и путь к первому найденному файлу. %~ftza1 - разворачивает %1 в строку, подобную DIR 

Таким образом, правильным будет использовать в качестве тега <script-dir> сочетание %~dp0
, которое будет раскрыто в полный путь к каталогу, где находится сценарий. Например,

 \packagebin.exe --recursive-search=yes --files-mask=exe,dll,pdb,obj ^ --archive-type=zip --archive-level=max --deliver-method=ftp ^ --deliver-target=ftp://ftp.site.com --deliver-source="%~dp0\bin" 

Обратите внимание на использование кавычек – потенциально каталог может иметь в своем пути пробел. Кавычки избавят от проблем в этом случае.

ПРЕДУПРЕЖДЕНИЕ

Можно ли написать на bat-языке серьезную программу?

Пожалуй, нет. Серьезная программа должна все-таки выглядеть серьезно. А все написанное на командном языке Windows таковым назвать можно лишь с о-о-о-чень большой натяжкой. Так что для решения более сложных задач автоматизации лучше все-таки взять что-нибудь более функциональное:

  • Perl
  • Python
  • Ruby
  • JScript / VBScript

Последние, кстати, присутствуют в Windows 2000/XP по умолчанию (с некоторыми функциональными различиями) и в целом могут считаться заменой *.bat языку. Однако сдается мне, что *.bat-файлы проживут еще очень долго.

Материалы по теме




Эта статья опубликована в журнале
RSDN Magazine

#2-2005. Информацию о журнале можно найти здесь

Как обработать текстовый файл?

Иногда в командном файле необходимо получить доступ к содержимому некоторого текстового файла и некоторым образом это содержимое обработать. Например, прочитать файл настроек программы.

Для привнесения еще большей конкретики в процесс изучения зададимся целью прочитать файл с настройками следующего содержания:

 buildmode=release
compiler=cl.exe
arch=x86 

Ничего сверхъестественного – простой key=value формат с возможностью вставки Unix-style комментариев. Помочь в чтении и обработке этого файла нам сможет команда for. Ее дополнительные опции позволяют задать и разделители, и символ начала комментария, и кое-что еще. Вот командный файл, который выполняет поставленную задачу:

 off :read_settings %~dp0\settings.txt || exit /b 1  Build mode : %BUILDMODE%   Compiler : %COMPILER%  /b 0
:read_settings SETTINGSFILE=%1  if not exist  %SETTINGSFILE% (  FAIL: Файл с настройками отсутствует  /b 1
) /f "eol=# delims== tokens=1,2" %%i in (%SETTINGSFILE%) ( %%i=%%j
) /b 0 

Кстати, возможности команды for не ограничиваются чтением из файла. Возможно также чтение вывода другой команды. Например, так:

 off /f "tokens=* usebackq" %%i (`cmd.exe /c ver`) ( VERSION=%%i
) 

Особенно меня умиляет наличие опции “usebackq”, которая делает синтаксис отдаленно похожим на юниксовый. И в стенах царства Билла есть граждане, скучающие по /bin/sh и пытающиеся хоть как-то скрасить существование свое и окружающих. Следующий совет это также косвенно подтверждает.

:/>  Диск d заполнен а файлов нет windows 7

Как сложить два числа?

Краткий ответ – смотри:

Длинный ответ таков. В bat-файлах можно производить довольно-таки продвинутые вычисления – продвинутые не в сравнении с другими языками, а в сравнении с отсутствием возможности что-либо вычислить вообще. Вычисление осуществляется командой set, если она выполняется с ключом /a. Поддерживается практически полный набор операторов языка C, включая шестнадцатеричный модификатор 0x. Переменные окружения в выражении не обязательно заключать в знаки процента – все, что не является числом, считается переменной. Подробнее – все-таки в man set, тьфу, то есть в set /?. А здесь напоследок – просто несколько примеров.

 off ARG=1 /a RESULT=ARG + 2 /a RESULT="ARG << 2" /a RESULT=0x1234 + 0x6786 

Решаем практические задачи на батниках

Время на прочтение

Батники это не мощный язык программирования, но, в то же время, на нем можно решить много рутинных задач. Цель статьи не просто рассказать о возможностях Windows-консоли, а показать их, решая практические задачи с которыми мне приходилось сталкиваться.

Подтверждение выполнения

 set answer=
set /p answer="Выполнить? [y/n]:"
if not "%answer%" == "y" exit /b 

Устанавливаем переменную answer в пустое значение (необходимо, для того чтобы затереть предыдущее значение, например, если батник исполняется несколько раз). set с ключом /p устанавливает значение переменной, которое вводится пользователем. Проверяем значение переменной и если оно не равно y завершаем выполнение батника.

Как получить текущий месяц, день, год и т.п.?

В батниках есть возможность получать подстроку используя синтаксис %variable:~m,n% Где variable это название переменной m – индекс первого символа, а n – количество символов подстроки.

 set fname=%date:~3,2%%date:~0,2% 

Лично мне такое понадобилось для задания ключа /d для xcopy.

Как вывести пустую строку в лог-файл?

Я не сразу догадался, что это можно делать вот так: 🙂

 echo.>> %logfile% 

Предыдущая команда выполнена успешно?

В большинстве случаев это:

 if %errorlevel%==0 ( echo OK>> %logfile%
) else ( echo ERROR #%errorlevel% >> %logfile%
) 

Архивирование файла с переменным именем

 for %%i in (c:\dir\#fe*.*) do rar a -ep c:\other_dir\%%~ni.rar %%i 

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

 for %%i in (c:\dir\#fe*.*) do 

мы выбираем все файлы по маске, исполняя команду rar a -ep c:\other_dir\%%~ni.rar %%i для каждого, где %%~ni это только имя файла.

Имя текущего исполняемого батника

 %~n0 

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

«Функция» в батниках

Если мы исполняем в одном батнике несколько повторяющихся команд, но с разными значениями переменных, то это можно реализовать так:

 set thebat=c:\Program Files\The Bat!\thebat.exe
set action=SEND
set mailto=email_1@domain.com
set subject=Subject_1
set attach=c:\dir\file????
call :mailit
set mailto=email_2@domain.com
set subject=Subject_2
set attach=c:\dir\file*.rar
call :mailit
…
exit
:mailit
@echo on
"%thebat%" /MAILTO="%mailto%";SUBJECT="%subject%";ATTACH="%attach%";%action% >> %logfile%
@echo off
exit /b 

Таким образом, у меня отсылается десяток разных файлов разным получателям, используя The Bat! Такой файл читать и редактировать намного удобнее, чем это было бы десять команд The Bat! подряд.

Получить последний по дате создание файл

Для начала получим список всех файлов, отсортированных по дате модификации:

 dir /b /od /a-d c:\dir\file_*.xls 

И пройдемся по нему циклом.

 for /f "tokens=*" %%a in (' dir /b /od /a-d c:\dir\file_*.xls ') do set "lastfile=%%a" 

Логично, что по завершению цикла в переменной %lastfile% у нас будет последний по дате модификации файл 😉

Выкачать файл по FTP

 ftp -s:file_to_ftp.txt 127.0.0.1 

Где файл file_to_ftp.txt будет у нас выглядеть следующим образом:

 login
password
bin
cd /files
put file.xls
quit 

Создаем нумерованные каталоги с инкрементом на единицу

 set dir_last=
for /f "tokens=*" %%i in ('dir /ad /b') do set dir_last=%%i
if '%dir_last%'=='' (set dir_last=000)
set dir_last=1%dir_last%
set /a dir_last = %dir_last% - 1000
set /a dir_new=%dir_last% + 1
set dir_new=00%dir_new%
set dir_new=%dir_new:~-3%
md %dir_new% 

Разобраться в коде предлагаю вам самим. 🙂 Основная возможность, которую я хотел показать данным примером, это использование ключа /a команды set для вычисления выражений. 😉

Как экранировать символ?

В командном языке Windows существует некоторый набор символов с высоким приоритетом, которые всегда трактуются как спецсимволы. К ним, в частности, относятся:

  • Операторы перенаправления ввода-вывода <, >, >>
  • Оператор конвейера |.
  • Операторы объединения команд ||, & и &&
  • Оператор разыменования переменной %…%.

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

  The ratio should be up to 10%.  

символ процента будет «съеден» интерпретатором, который решит, что это попытка вывода значения какой-то переменной. В случае со знаком процента решение довольно хорошо известно и состоит в удвоении этого символа:

  The ratio should be up to 10%%.  

после чего все заработает так, как надо. Однако в других случаях все менее очевидно. Рассмотрим командный сценарий, который генерирует незатейливый HTML-файл:

     OUTPUTFILE=%1 >%OUTPUTFILE% >>%OUTPUTFILE%  <title>This is a greeting page</title>  >>%OUTPUTFILE% >>%OUTPUTFILE% >>%OUTPUTFILE% >>%OUTPUTFILE% >>%OUTPUTFILE% >>%OUTPUTFILE% 

К сожалению, при попытке запуска этого “чуда инженерного разума” нас постигнет неудача в виде сообщения об ошибке

 > was unexpected at this time. 

Оно и понятно: командный интерпретатор не в силах разобраться, где его просят вывести на экран символ HTML-тега, а где перенаправить вывод. В нормальных языках программирования эта проблема обычно решается обрамлением строковых литералов кавычками. Отчасти это помогает и в bat-файлах. Но лишь отчасти. Выполнение строки

 >%OUTPUTFILE% 

приведет к тому, что в выходной файл будут записаны и сами кавычки. Это явно не совсем то, что требуется.

:/>  «Инструкции по процессу установки оперативной памяти для ноутбука Acer, а также рекомендации по увеличению объема оперативной памяти ноутбука Acer Nitro 5»

К счастью, есть один малоизвестный способ, позволяющий добиться требуемого результата. Символ ^ позволяет экранировать любой другой символ с безусловным приоритетом. Таким образом, вышеприведенный пример генерации HTML может быть успешно записан так:

 off OUTPUTFILE=%1 >%OUTPUTFILE% >>%OUTPUTFILE%  >This is a greeting page  >>%OUTPUTFILE% >>%OUTPUTFILE% >>%OUTPUTFILE% >>%OUTPUTFILE% >>%OUTPUTFILE% >>%OUTPUTFILE% 

А можно создать в bat-файле функцию?

Да, можно. Более того, иногда даже нужно. Правда, функциями это можно назвать условно. Есть особый синтаксис команды call, который позволяет перейти на метку в этом же bat-файле с запоминанием места, откуда был произведен этот вызов:

Возврат из функции производится командой:

 /b [опциональный код возврата] 

Ключ /b здесь очень важен: без него будет произведен выход не из функции, а из сценария вообще.

За подробностями обращайтесь к:

Что интересно, команда call с таким синтаксисом поддерживает рекурсивные вызовы с автоматическим созданием нового фрейма для переменных аргументов %0-%9. Иногда это может быть полезным. Вот классический пример рекурсивного подсчета факториала на командном языке:

 off :factorial %1 %RESULT%
:factorial %1 == 0 ( RESULT=1 /b
) %1 == 1 ( RESULT=1 /b
) /a PARAM=%1 - 1 :factorial %PARAM% /a RESULT=%1 * %RESULT% /b 
 > factorial.bat 10
3628800 

Как получить короткое (8. 3) имя файла?

ПРЕДУПРЕЖДЕНИЕ

Доступ к файлу по короткому имени может быть не всегда возможен. На файловой системе NTFS создание коротких псевдонимов для файлов может быть отключено путем установки в единицу значения «NtfsDisable8dot3NameCreation» в ключе реестра «HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem».

Итак, все же (в предположении, что надругательства над NTFS не было) – как? Внимательный читатель должен был заметить в предыдущем разделе, что при обращении к переменным %0 – %9 можно использовать префикс

 %~s1 - expanded path contains short names only 

который нам как раз мог бы помочь. Но есть засада – все эти полезные префиксы нельзя использовать с произвольной переменной окружения, а присваивание переменным %0 – %9 не поддерживается. К счастью, описываемые префиксы можно еще использовать с переменными цикла for, и это дает нам способ достичь требуемого результата. Например, вот так можно получить 8.3-путь к “Program Files”:

 /d %%i ("%PROGRAMFILES%") ( PROGRAMFILESSHORT=%%~si
)  8.3-имя для каталога "%PROGRAMFILES%" -^> "%PROGRAMFILESSHORT%"  

Этот и другие модификаторы можно использовать и с любой другой формой цикла for, подробнее о которых можно узнать из:

Как перенести длинную строку?

Совет по поводу экранирующего символа ^ имеет еще одно применение: перенос строк. Я (как и многие из вас, наверное) люблю, чтобы любой исходный текст, который я пишу, выглядел красиво – даже *.bat-файлы. Одним из обязательных условий красоты и удобочитаемости кода для меня является его ширина: все строки должны умещаться в 78 столбцов. Можно поспорить по поводу числа 78, но в одном я непреклонен – ограничение на ширину текста кода должно быть, иначе это не код, а макароны.

Так вот долгое время *.bat-файлы портили мне жизнь тем, что иногда приходилось писать длинную строку – например, вызов какой-нибудь другой программы с кучей опций, и я не знал, что с этим делать. Происходило это нечасто, но всегда было неприятно. Но, к счастью, моя жизнь изменилась с тех пор, как я открыл для себя Супер-Символ ^:

 packagebin.exe --recursive-search=yes --files-mask=exe,dll,pdb,obj --archive-type=zip --archive-level=max --deliver-method=ftp --deliver-target=ftp://ftp.site.com 

Помните лишь, что чудо-символ должен быть последним в строке – скажите «Нет!» концевым пробелам.

Как перенаправить стандартный вывод в файл?

Плоха та короткая программа, которая не стремится стать большой. К сожалению, это правило применимо и к командным файлам Windows тоже – иногда bat-файлы вырастают до довольно больших размеров. Если при этом результат выполняемых команд должен журналироваться, то все становится совсем плохо – почти каждая строка имеет хвостик типа

  Cleaning up the target directory  >>%LOGFILE%
.  The target directory has been cleaned  >>%LOGFILE% 
 off OUTPUT=out.html "%STDOUT_REDIRECTED%" == "" ( STDOUT_REDIRECTED=yes cmd.exe /c %0 %* >%OUTPUT% /b %ERRORLEVEL%
)  ^<title^>This is a greeting page^</title^>  

Здесь делается то же, что и раньше, но с перенаправлением стандартного вывода в файл out.html. Делается это простым способом – перезапуском сценарием самого себя. Сначала проверяется, не установлена ли переменная окружения STDOUT_REDIRECTED. Если она установлена, значит, сценарий уже перезапущен с перенаправленным выводом и можно просто продолжить работу. Если же переменная не установлена, то мы ее устанавливаем и перезапускаем скрипт (cmd.exe /c %0) с таким же набором параметров, что и исходная команда (%*) и перенаправленным в файл стандартным выводом (>%OUTPUT%). После завершения выполнения «перенаправленной» команды выходим.