Перенос строки в командной строке windows

Обновлено: 02.07.2024

Конфигурация компьютера
Процессор: AMD FX 8300
Материнская плата: Gigabyte GA-970A-UD3
Память: 2х2 Гб Kingston DDR3-1333, 2х4 Гб Kingston DDR3-1333
HDD: 250Гб(SSD Samsung 860EVO) +500Гб(ST3500418AS)+2000Гб(ST2000DM001)
Видеокарта: Radeon X1650
Блок питания: Be Quiet SYSTEM POWER 9 500W [BN246]
CD/DVD: Optiarc DVD RW AD-5280S
Монитор: Dell UltraSharp U2414Hb
ОС: Windows 7 x64

которая в цикле ставит приложения. Проблема в том, что весь вывод идёт в одну строку. Как набрать и после <nul echo %errorlevel% вставить символ перевода коретки 08H на новую строку?

В качестве ликбеза, какие ещё такого типа символы существуют для командной строки? Можно-ли разукрасить код возврата errorlevel?

sov44, «08H» — не «символ перевода к а ретки», а «Backspace», возврат на один символ.

Для вывода пары символов CrLf достаточно команды «echo.» (именно с точкой, сразу, без пробела, вослед «echo»).

В качестве ликбеза, какие ещё такого типа символы существуют для командной строки? »

4 Управляющие символы. Работают в консоли командной строки, понятно, далеко не все, это не терминал.

В принципе, можете попробовать: CMD/BAT: Вывод разноцветного текста — CMD/BAT — Коллекция скриптов и идей — Серый форум (здесь, кажись,тоже было что-то подобное, но не найду).

Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Конфигурация компьютера
Процессор: AMD FX 8300
Материнская плата: Gigabyte GA-970A-UD3
Память: 2х2 Гб Kingston DDR3-1333, 2х4 Гб Kingston DDR3-1333
HDD: 250Гб(SSD Samsung 860EVO) +500Гб(ST3500418AS)+2000Гб(ST2000DM001)
Видеокарта: Radeon X1650
Блок питания: Be Quiet SYSTEM POWER 9 500W [BN246]
CD/DVD: Optiarc DVD RW AD-5280S
Монитор: Dell UltraSharp U2414Hb
ОС: Windows 7 x64
Iska, осталось понять, как набрать в батнике «08H» или к примеру «07H»
Для вывода пары символов CrLf достаточно команды «echo.» »
Iska, осталось понять, как набрать в батнике «08H» или к примеру «07H» »
В редакторе Far Manager'а, коим я пользуюсь, нет ничего проще — посредством «Ctrl-Q»:

«0x08» — «Ctrl-Q», «Ctrl-H» («H» — восьмая буква английского алфавита, посему «Ctrl-H» в консоли вводит символ с кодом «0x08»); «0x07» — соответственно «Ctrl-Q», «Ctrl-G» («G» — седьмая буква английского алфавита, посему «Ctrl-G» в консоли вводит символ с кодом «0x07»).

Вот как это может выглядеть (скопируйте код и вставьте в редактор Far Manager'а, поскольку визуально управляющие коды здесь не видны):


Здесь же можете увидеть и пример работы с «echo.» после «<nul set /p …».


В редакторе Far Manager'а, коим я пользуюсь, нет ничего проще — посредством «Ctrl-Q»: »

-------
Мнение большинства людей всегда ошибочно, ибо большинство людей - идиоты.

yurfed, я давно убедился в том, что Far Manager, как и Microsoft Office, неисчерпаем: казалось бы — давно знаком, хорошо ориентируешься, знаешь почти наизусть, а нет-нет — да и выудишь что-то новое, казалось бы, лежащее на поверхности. Смотришь и думаешь — ну, как я раньше-то на это не обратил внимания, элементарно же.

Вот за это я его и люблю — что посредством него можно реализовать практически всё потребное в плане менеджмента файлов (для чего он, собственно, и предназначен). А уж в третьей версии, где «искаропки» теперь доступен полноценный входной ЯВУ Lua — так и вовсе… Дело осталось за малым — набраться решимости и переползти со второй на третью версию .

Конфигурация компьютера
Процессор: AMD FX 8300
Материнская плата: Gigabyte GA-970A-UD3
Память: 2х2 Гб Kingston DDR3-1333, 2х4 Гб Kingston DDR3-1333
HDD: 250Гб(SSD Samsung 860EVO) +500Гб(ST3500418AS)+2000Гб(ST2000DM001)
Видеокарта: Radeon X1650
Блок питания: Be Quiet SYSTEM POWER 9 500W [BN246]
CD/DVD: Optiarc DVD RW AD-5280S
Монитор: Dell UltraSharp U2414Hb
ОС: Windows 7 x64

Iska, довольно интересный мануал. Однако Far Manager_ом никогда не пользовался, а только по старинке Total Commander
Текст вставил, но символы не увидел. Если набирать вручную «Ctrl-Q», «Ctrl-H», символы вижу.

Есть иной, чем Far Manager_ом набирать символы?

Последний раз редактировалось sov44, 10-12-2015 в 20:51 .

Это печально. У меня под Mozilla Firefox нормально с этого форума копирует. Могу вложить файл в архиве, если есть ещё потребность. Выкладывать?

Можете ещё включить в настройках редактора отображение пробельных символов:

В Unix я бы просто использовал vi , но я не знаю, что это за команда в Windows. Я на самом деле пытаюсь редактировать файлы через SSH с Windows Server 2008.

Я думаю, что принятый ответ должен быть изменен на squillman (так как он единственный, который будет работать на большинстве современных ПК - и, возможно, внутри контейнеров Docker). если вы делаете есть графический рабочий стол , а просто хотите отредактировать файл непосредственно с , cmd то вы можете использовать , например , блокнот с notepad myfile.txt

edit filename

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

Изменить: За исключением 64-разрядных версий Windows.

На всех версиях Windows? В Windows 7, по-видимому, нет «правки». Странно . очевидно, он установлен по умолчанию в Windows 7 32-разрядной, но не в Windows 7 64-разрядной. Печально. @nhinkle: Кажется, я вспомнил, что читал что-то о том, что 16-битные приложения недоступны при установке 64-битных окон. Подтверждено, что НЕ работает в Win 10 . Я действительно не могу поверить, что в Windows нет таких базовых инструментов, и, кажется, никому нет до этого дела

Самое простое решение для всех версий Windows:

И никакого дополнительного программного обеспечения не требуется.

Ах. Правильно. В Windows нет встроенного редактора командной строки. Возможно, вам потребуется установить версию редактора Gnu, которую вы хотите использовать. Поскольку вы уже установили ssh сервер, это не должно быть проблемой для вас. Как OP сказал . «Я на самом деле пытаюсь редактировать файлы через ssh . » бесполезный ответ, как для пользователей , SSH и для тех , кто хочет редактировать файлы В CMD окна, а не за его пределами Это не будет работать в контейнере Docker на основе 'windowsservercore'

В командной строке Windows введите copy con и имя целевого файла. ( copy con c:\file.txt ).

Затем введите текст, который вы хотите поместить в файл.

Завершите и сохраните файл, нажав CTRL - Z тогда Enter или F6 потом Enter .

Если вы хотите изменить текст в существующем файле, просто отобразите текст, используя команду, type после которой следует имя файла, а затем просто скопируйте и вставьте текст в copy con команду.

Жесткое ядро. Старайтесь не делать опечаток, или вам придется начинать все сначала. Ну, Backspace работает, если вы поймете ошибку, прежде чем нажать Enter. Кажется, не работает с psexec. Попытался отредактировать мой файл hosts с помощью, copy con hosts но ^ Z не сохраняет и ^ C не отменяет! Пришлось закрыть окно cmd, чтобы выйти. Файл не изменился. В контейнере Docker, основанном на «windowsservercore» (CMD), Ctrl + C работал для завершающей последовательности клавиш.

Если вы привыкли к vi и не хотите соглашаться на встроенный редактор, вы можете получить Vim для Windows . Он будет работать из командной оболочки. Или попробуйте WinVi .

это должно быть помечено как ответ, потому что edit он был удален из победы 10 Это гораздо лучше, чем это: он также работает внутри контейнера Windows Docker (проще всего получить «исполняемый файл консоли Win32», например, vim81w32.zip - распаковать и скопировать vim.exe туда, где он доступен в контейнере Docker).

Хотите верьте, хотите нет, EDLIN.EXE по <shudder> крайней мере , все еще есть в этой системе Vista.

Извините, пока я тихо рыдаю про себя .

Он был окончательно удален в Windows 7 (по крайней мере, в 64-битных версиях). Edlin - 16-битная программа, поэтому она недоступна в 64-битных версиях Windows. Тем не менее, я не удивлюсь, если кто-то здесь

Я не знаю ни о SSH, ни о чем-либо (еще?) Связанном с сервером, так что извините, если это «решение» бесполезно. Если вы хотите редактировать файлы в командной строке, вы можете получить версию Nano для Windows .

В качестве примечания, эти маленькие ^ знаки внизу окна должны представлять Ctrl кнопку. Например, ^X Exit означает, что вы можете выйти из программы, используя Ctrl - X .

Кроме того, Nano иногда добавляет дополнительные символы новой строки при сохранении файлов. Кажется, это какая-то ошибка с переносом слов Нано.

Я также видел порты vi для Windows, хотя я использовал тот, который просто делает окно командной строки настолько маленьким, насколько это возможно, оставляя только строку заголовка (что означает, что остальная часть окна также может быть невидимой , так как вы не можете видеть, что вы делаете). Тем не менее, версия Vim для Windows, кажется, работает довольно хорошо.

Как вы можете вставить новую строку из вывода командного файла?

Я хочу сделать что-то вроде:

Пригодился для меня. Я должен был сделать эхо \ n \ n | my_app.exe в скрипте. Я сделал (эхо. && эхо.) | my_app.exe Простой подход «Код начинается:»> echo hello & echo world, даст вам то, что вам нужно Вы можете вставить невидимую ascii chr (255) в отдельную строку, которая вызовет пустую новую строку. Удерживая клавишу [alt], нажмите 255 на клавиатуре. это вставляет chr (255), который является пустым квадратом. т.е. " echo (alt + 255) " Вы можете использовать только клавиатуру, а не цифры в верхней части клавиатуры Querty! Так же, как половина ремонта компьютеров включает и включает его, половина разработки программного обеспечения - это то, что я называю космической инженерией . Нам нужны наши пустые строки просто так.

echo hello & echo.world

Это означает, что вы можете определить & echo. как константу для новой строки \n .

в примере не нужен период, но он нужен для echo. && echo hello && echo. && echo world Период вещь в "эхо". никогда не перестает удивлять меня. Это так устарело, и все же я всегда забываю, что точка должна быть строго соединена с именем команды без пробелов между ними. В вашем посте нет ошибок, я пишу это просто как напоминание: «эхо». ! = "Эхо." ! @quetzalcoatl, это становится еще более странным. Другие символы, кроме точки, тоже работают. В SS64 говорится, что лучший синтаксис - echo( для повышения производительности (но все же без места). Расширенное обсуждение других персонажей и их достоинств / недостатков в ECHO. Не в состоянии дать текст или пустую строку - Вместо этого используйте ECHO / Возможно ли это при предоставлении строки внутри одного оператора echo? Почему вам нужно сделать это с помощью одного эхо-оператора; где вред иметь другого? @ Роб, я только столкнулся с этой проблемой, и ни одна из этих работ. Вы должны повторить в одном утверждении в моем примере. Я генерирую некоторые текстовые файлы из HTML и создаю Makefile, используя echo "Makefile contents (which has \n)" > Makefile несколько эхо, это не сработает Используйте & (или &&), чтобы сделать их в одном выражении: например, чтобы поместить «hello \ nworld» в текстовый файл: (echo hello & echo world) >> ./test.txt Для многострочного вывода в файл, почему бы просто не сделать следующее? echo line 1 > Makefile а потом echo line 2 >> Makefile . Использование >> аргументов приводит к добавлению вывода в файл, что является именно тем поведением, которое необходимо для этого случая.

Вот, пожалуйста, создайте файл .bat со следующим:

Вы должны увидеть результат, подобный следующему:

Очевидно, вам нужен только код между операторами REM.

Очень впечатляет, не могли бы вы объяснить, как работает набор строк NL = ^^^% NLM %% NLM% ^% NLM %% NLM%? Я не могу полностью понять это Это прекрасный пример, показывающий, что командные файлы cmd.exe и Windows абсолютно безумны! ПРИМЕЧАНИЕ ДЛЯ САМОСТОЯТЕЛЬНОЙ: строка «set NLM = ^» не должна иметь ничего после CARET и должна иметь 2 пустых строки после нее. Смотрите мой ответ для более простого метода. set nl=^&echo. , тогда просто echo hello %nl% world дает тот же эффект.

В echo: cmd / bat-файлах есть стандартная функция записи пустой строки, которая эмулирует новую строку в вашем cmd-выходе:

Вывод приведенного выше cmd-файла:

Единственная версия, которая всегда работает echo( . Похоже, это может вызвать проблемы, но на самом деле работает отлично. Все другие формы имеют по крайней мере одну ситуацию, когда команда не будет работать так, как нужно. @Pacerier, здесь достаточно эха для отдельного вопроса. Возможно, что-то вроде «какие персонажи могут сразу следовать echo и каковы их эффекты?»

Как и ответ Кена, но с использованием отложенного расширения.

Сначала создается отдельный символ перевода строки и присваивается переменной \ n.
Это работает, когда каретка в конце строки пытается экранировать следующий символ, но если это перевод строки, он игнорируется, а следующий символ читается и экранируется (даже если это также перевод строки).
Затем вам нужен третий перевод строки для завершения текущей инструкции, иначе третья строка будет добавлена ​​к LF-переменной.
Даже командные файлы имеют окончание строк с CR / LF, важны только LF, так как CR удаляются на этом этапе анализатора.

Преимущество использования отложенного раскрытия состоит в том, что вообще нет специальной обработки символов.
echo Line1%LF%Line2 потерпит неудачу, так как синтаксический анализатор прекратит синтаксический анализ на одной строке.

Редактировать: избегать echo.

Это не отвечает на вопрос, так как вопрос был об одном echo который может выводить несколько строк.

Но, несмотря на другие ответы, которые предлагают использовать echo. для создания новой строки, следует отметить, что echo. это наихудший вариант, поскольку он очень медленный и может полностью потерпеть неудачу, так как cmd.exe ищет файл с именем ECHO и пытается его запустить.

Для печати только пустой строки, вы можете использовать один из

Но использование echo. , echo\ или echo: следует избегать, так как они могут быть очень медленным, в зависимости от места , где скрипт будет выполняться, как сетевой диск.

Урок bat-аники

Однако в нашей повседневной деятельности встречаются и вещи, которые не так интересны и интеллектуальны. Мы не очень любим говорить об этом, делаем вид, что Это – грязно, нечистоплотно и недостойно нашего внимания. Однако, приходит день, приходит час и перст Судьбы находит нас – нам надо написать еще один батничек… Иногда это запускалка для построения проекта, которая должна при ошибке компиляции скопировать логи на сетевой диск, иногда – запуск обновления исходных текстов из SVN. Иногда – что-нибудь еще.

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

Наш урок будет построен по сугубо практическому принципу, известному в народе как Cookbook. Иными словами, я не буду вдаваться в синтаксические и семантические дебри командного языка Windows, а лишь продемонстрирую его возможности (хотел написать «мощь», но все-таки передумал). Именно поэтому большинство следующих заголовков будет начинаться со слова «Как». Впрочем, для полноты по ходу развития событий будут даваться подробные комментарии, в том числе и по языковым конструкциям.

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

Практически все описанные здесь рецепты подойдут только для Windows 2000 и старше. Bat-язык Windows 9x, к счастью, можно считать почившим, так что здесь он не рассматривается. Более того, диалекты cmd.exe операционных систем Windows 2000, Windows XP и Windows Server 2003 также немного различаются. Все приведенное ниже создано и проверено на компьютере под управлением операционной системы Windows XP. За подробной информацией по различиям в реализации той или иной команды обращайтесь к [1].

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

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

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

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

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

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

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

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

Таким же способом можно экранировать любой другой специальный символ. Очевидно, можно экранировать и сам ^. Не очень эстетично, зато дешево и практично. Слово «надежно» я пропустил умышленно…

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

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

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

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

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

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

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

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

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

Таким образом, правильным будет использовать в качестве тега <script-dir> сочетание %

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

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

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

Опасайтесь бездумного применения команды cd %

dp0 без проверки результата выполнения. Теоретически, эта команда должна сменить текущий каталог на каталог, в котором расположен командный файл. Как правило, это работает. Однако возможны неожиданности. Однажды был написан простой командный сценарий, задача которого была просто удалить все каталоги рядом с собой. В «свою» директорию он переходил как раз через cd %

dp0. Все было проверено на локальной машине – работало замечательно. После этого сценарий был помещен на файл-сервер, где ему и полагалось быть. Я зашел с помощью Far в сетевой каталог, и для контрольной проверки решил запустить файл еще раз. Дальнейшее словно в тумане. cmd.exe правильно определил местонахождение bat-файла: \\servername\sharename\directory. Однако при попытке сделать туда cd, он сказал, что UNC-пути в качестве текущих каталогов не поддерживаются и лучше он сменит текущий каталог на C:\WINDOWS… Это было действительно мудрое решение… Часть сценария, отвечавшая за удаление всех каталогов, сработала отлично – хорошо, что я успел вовремя остановить это безумие.

В тот день я узнал, что такое System Restore…

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

«А зачем? – спросите вы – Ведь мы живем в мире Интернета, Web-сервисов и NTFS с длинными именами файлов». Это действительно так, но иногда встречаются программы, которые отчаянно сопротивляются прогрессу, и в частности, не любят имен файлов и полных путей с пробелами. Одной из таких программ, кстати, является утилита build.exe из Windows DDK… В таких ситуациях спасает использование короткого, «беспробельного» DOS-имени для файла.

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

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

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

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

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

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

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

Такое «единовременное» перенаправление имеет и еще один неочевидный плюс: файл открывается и закрывается только один раз, и всем командам и дочерним процессам передается дескриптор уже открытого файла. Во-первых, это чуть-чуть улучшит производительность (жизнь удалась – сроду бы не подумал, что буду когда-нибудь писать о производительности в bat-файлах). Во-вторых, это поможет избежать проблемы с невозможностью открыть файл для записи. Такое может случиться, если после выполнения одной из команд останется «висеть» какой-нибудь процесс. Он будет держать дескриптор интересующего нас файла и перенаправление вывода в этот файл для всех последующих команд провалится. Проблема может показаться надуманной, но однажды она украла у меня 2 часа жизни…

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Решается эта проблема путем использования отложенного раскрытия переменных. Переменные, заключенные в !…! вместо %…%, будут раскрыты в их значения только в момент непосредственного использования. Данный режим по умолчанию отключен. Включить его можно либо использованием ключа /V:ON при вызове cmd.exe, либо использованием команды

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

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

Вот теперь это почти полноценный if-then-else блок. Почти, потому что если в одной из команд echo у вас встретится закрывающая круглая скобка, то вам необходимо заэкранировать ее символом ^, иначе синтаксический анализатор путается…

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

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

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

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

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

Обильные комментарии должны помочь легко разобраться, что к чему. За подробностями, как обычно, отошлю к:

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

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

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

Это операторы &, && и ||. Они практически совсем не освещены в документации, но полезны в повседневности. Они позволяют объединять несколько команд в одну, т.е. примерно так:

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

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

Я был приятно удивлен, узнав, что cmd.exe тоже умеет выполнять такие конструкции. Это безопаснее и правильнее, нежели простое последовательное выполнение этих команд, и короче и проще, чем строгая проверка и обработка кодов возврата. Очень удобно при написании на скорую руку. Не менее полезен иногда и оператор ||. Суть его тоже логична – выполнить вторую команду, если первая дала сбой. Часто встречается в таких идиомах:

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

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

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

  • Perl
  • Python
  • Ruby
  • JScript / VBScript

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

Читайте также: