Задание логических условий поиска в cmd. Справка по команде if и ее параметрам. Создание поколений архивов по датам и времени

). Он в основном практический: что выбрать, что можно ставить и что нельзя, ну и различные полезности. Однако он не затронул, пожалуй, самую интересную часть - а как память вообще работает, и как ее тонко настроить (и разогнать). Если посмотреть, то по количеству параметров ОЗУ является чуть ли не самым сложным элементом ПК: посудите сами, для процессора вы в лучшем случае можете менять частоту тактового генератора (FSB, да и к тому же она уже лет 15 как 100 МГц и редко кто ее трогает), множитель (его как раз и меняют) и напряжение (ибо для работы на более высоких или низких частотах всегда можно подкорректировать напряжение для стабильности работы и, в некоторых случаях, меньшего энергопотребления), ну и количество рабочих ядер (хотя мало кто будет их трогать - разве что многопоточность отключают, ибо в некоторых задачах она может дать отрицательный прирост). Все остальные параметры уже индивидуальны и есть не у всех процессоров, так что зачастую их и не трогают. Что касается видеокарт, то тут параметров еще меньше - всего-то частоты GPU, памяти и напряжение GPU. Но если мы посмотрим на ОЗУ, то увидим море важных параметров: задержки, частоты, транзакции в секунду и т.д. - давайте разберемся, что это и как связано с производительностью и стабильностью работы памяти.

Технические характеристики памяти

Для начала нужно понять, что означают те или иные циферки и буковки в спецификациях памяти. Посмотреть их можно или на самой памяти, или на ее коробке, или в специальных программах типа AIDA64. Я разберу на примере своей памяти, но у вас будут схожие данные. Итак, вот скриншот из AIDA64:

Что мы видим про память? То, что она Dual Channel DDR4-3200 SDRAM (16-18-18-36-CR2). Если погуглить маркировку самих чипов, то можно узнать еще немного информации - PC4-17000 1.2 В. Пойдем по порядку. Что означает Dual Channel (у вас может быть и Single, и Triple, и Quad - хотя если у вас последнее, то вы, скорее всего, знаете, что это)? Это означает, что память работает в двухканальном режиме (или одноканальном, или в трехканальном, четырехканальном и т.д.). Если у вас стоит одна планка памяти, то она будет работать в одноканальном режиме - то есть характеристики чтения и записи будут приблизительно такими же, которые указаны на ней (на деле все зависит от контроллера памяти, и на практике значения могут быть на 10-15% ниже). Если у вас стоит две и больше планок с одинаковыми характеристиками, то они могут работать вместе: в таком случае объем увеличивается пропорционально числу модулей, и скорость также растет почти линейно. Поэтому если у вас одноканальная память и интегрированная графика, которая использует ОЗУ как видеопамять, и если вы на ПК занимаетесь чем-то серьезнее просмотра фильмов и сидения в интернете - в первую очередь нужно купить еще одну планку ОЗУ и сделать двухканальный режим (как это делается - написано в практической статье), ибо вы тем самым фактически удваиваете производительность ОЗУ (ну а двухканальные контроллеры памяти имеют 90% современных процессоров).

Идем дальше - сочетание букв DDR SDRAM (Double Data Rate Synchronous Dynamic Random Access Memory - синхронная динамическая память с произвольным доступом и удвоенной скоростью передачи данных). Здесь нам интересна только концовка - «и удвоенной скоростью передачи данных». Смысл тут в том, что в старом типе памяти SDRAM данные считывались только при переходе из стостояния «0» в состояние «1» (по фронту сигнала). В DDR же решили считывать данные и при переходе из состояния «1» в состояние «0» (по спаду сигнала), то есть реальная частота памяти удвоилась. Однако с аппаратной точки зрения частота памяти остается той же, поэтому, например, в том же CPU-Z частота памяти будет вдвое ниже, чем в диспетчере задач:


Как я уже объяснил выше - пугаться этого не стоит, это особенность DDR.

Далее - что означает четверка в DDR4? В общем-то только одно - что это 4ое поколение памяти DDR. Отличия между всеми типами можно посмотреть на Вики, не вижу особого смысла это переписывать, но скажу, что основной прирост идет за счет роста частоты памяти.

Теперь посмотрим всю конструкцию - DDR4-3200. Очень многие после 3200 подписывают МГц - в общем-то, это не совсем правильно. На самом деле тут имеется ввиду МТ/с, или мегатранзакции в секунду. Что это за величина? Это величина, которая показывает, сколько операций в секунду может совершаться с памятью. С учетом того, что ширина шины DDR4 составляет 64 бита (или 8 байт), можно получить ее скорость в МБ/с - для этого нужно 3200 МТ/с * 8 Б = 25600 МБ/с. И тут следует сказать, что эта цифра зачастую уже пишется на самой памяти - в моем случае это PC4-17000. Вы скажете - 17000 не равно 25600. Все верно, в моем случае память разогнана, если взять ее реальную скорость в 2133 МТ/с то мы как раз получим 17000 МБ/с. Ну а PC4 в данном случае - эквивалент DDR4. То есть, как вы видите, DDR4-2133 и PC4-17000 - эквивалентные записи, поэтому для понимания того, какая у вас память, достаточно знать только одну из них.

Теперь идет конструкция 16-18-18-36-CR2. Для объяснения этих цифр нужно посмотреть, что же из себя представляет современная DDR-память. По сути она - набор ячеек, хранящих информацию. Каждая ячейка имеет внутри себя транзисторы и конденсаторы, и располагается она в двумерном массиве вместе с другими ячейками. Ну а принцип действия прост: конденсаторы заряжаются при записи в ячейку единичного бита и разряжаются при записи нулевого бита. Отсюда, кстати, возникает проблема - дабы избежать разрядки конденсаторов и потери информации, их нужно постоянно заряжать - именно поэтому при отключении питания ПК вся информация из ОЗУ стирается.

Основная проблема при работе с ОЗУ - это задержки (latency) при доступе к ячейкам памяти. Логично, что чем меньше задержка - тем быстрее будет идти чтение/запись - тем меньше будет простаивать процессор в ожидании ответа от ОЗУ - тем быстрее будет быстродействие. Посмотрим, какие бывают задержки и за что они отвечают.

Разумеется, каждая ячейка имеет свой «адрес»: грубо говоря, это ее номер в строке и столбце таких же ячеек в двухмерном массиве. В свою очередь, некоторое количество ячеек объединяется вместе для более быстрого доступа к ним - такая группа называется банком. Теперь посмотрим, что происходит, когда контроллер памяти хочет что-то записать в определенную ячейку. Для начала он обращается в банку с адресом строки - этот сигнал называется RAS (Row Address Strobe). Соответственно, время обращения (задержка) называется RAS Latency - но этот параметр малоинформативен и очень редко пишется. Зато важен параметр RAS to CAS Delay - это процесс поиска нужной строки в банке памяти. Вот этот параметр уже нужен, и его задержка пишется второй - то есть в моем случае он составляет 18 тактов (один такт - это одна отправка данных по шине памяти). Великолепно, всего за 18 тактов мы нашли нужную строку. Но ведь нужен еще и столбец - за него отвечает еще один сигнал, CAS, и его задержка пишется первой - в моем случае это 16 тактов. Казалось бы - все, мы получили точное расположение нашей ячейки, зачем еще две цифры?


Не все так просто - зачастую бывает, что контроллеру нужно обратиться к другой ячейке этой же строки. Но для этого он должен сначала закрыть предыдущую сессию запроса (нельзя одновременно обращаться к различным ячейкам одной строки) - а на это опять же уходит время, и эта задержка называется RAS Precharge - она указывает на время закрытия и повторной активации строки. Ее пишут третьей, в моем случае это опять же 18 тактов. Последний параметр - Cycle Time - отвечает за время, необходимое для полного открытия и закрытия всего банка, иными словами - это быстродействие всей памяти. Он пишется четвертым, и у меня он 36 тактов.

Остался последний параметр - CR (Command Rate), он может быть 1 или 2. Отвечает этот параметр за время, которое должно пройти между активацией памяти и ее способности к работе - это 1 или 2 такта. Разумеется, 1 такт лучше, но тут уж как повезет с памятью.

Разумеется, такой параметр как такт не очень нагляден - интереснее узнать результат в наносекундах. Для этого узнаем, сколько времени занимает один такт - это 1 / 1200 МГц = 0.83 нс (берем, разумеется, реальную частоту памяти). Cycle Time у памяти 36 тактов, то есть задержка получается 0.83 нс * 36 = 30 нс. Тогда почему AIDA64 показывает результат около 48 нс? Все просто - сам процессор хоть и небольшой, но из-за крайне малых промежутков времени (миллиардные доли секунды) приходится учитывать время на проход сигнала внутри него, что и добавляет дополнительные 18 нс.

Вот в общем-то и все, теперь Dual Channel DDR4-3200 SDRAM (16-18-18-36-CR2) для вас не просто куча символов, а вполне осмысленный набор параметров, который позволяет достаточно точно понять, что за ОЗУ перед вами.

Разгон ОЗУ

У внимательного читателя мог возникнуть вопрос - а что же важнее, более высокая частота памяти или более низкие тайминги (задержки)? Ведь, с одной стороны, чем выше частота - тем быстрее производительность памяти и системы в целом. С другой стороны, чем ниже тайминги - тем быстрее будет происходить обращение к памяти и меньше будет простаивать CPU, то есть - тем быстрее будет работать ПК. С учетом того, что чем выше частота - тем выше тайминги, тут нужно соблюсти баланс. Увы - у каждого он свой, так что разгон памяти - достаточно кропотливое занятие по выставлению различных таймингов, напряжений и частот, и тесты скорости работы ОЗУ в системе. Разумеется, далеко не все хотят заниматься перебором, поэтому в продаже есть память с поддержкой профилей DOCP и XMP. Это - уже зашитые в память профили авторазгона, где прописаны напряжения, частоты и тайминги, на которых память гарантированно заработает - вам лишь нужно выбрать нужный профиль в UEFI. Плюсы такого метода очевидны - вы получаете разгон в один клик. Минусы тоже - во-первых, такая память стоит дороже, причем чем выше гарантированная частота - чем больше цена. Во-вторых, профили не идеальны, и зачастую можно выжать еще 5-10% производительности, но опять же - ковыряясь в таймингах.

Ну и самый последний ожидаемый вопрос - а стоит ли вообще разгонять ОЗУ? Все зависит от ваших задач и процессоров: к примеру, в 6 и 8-ядерных AMD Ryzen частота шины, связывающей два процессорных кристалла, напрямую зависит от частоты ОЗУ, так что там ее разгон как говорится «маст хэв». В играх особого прироста производительности от разгона памяти стоит ждать лишь в топовых системах, и то это будет разница между 110 и 120 fps - с одной стороны, приятный бонус, с другой - разница-то все равно не заметна на глаз. Ну а лучше всего заметен разгон в задачах, тесно связанных с ОЗУ - к примеру, архивацией, где у процессоров зачастую не хватает кэша, и они вынуждены часто обращаться к памяти.

Оперативная память: история развития и принципы работы

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

Специалисты, исследующие историю развития вычислительной техники, считают первой вехой на тернистом пути возникновения и развития компьютеров разработку британцем Чарльзом Бэббиджем аналитической машины в Лондоне в далеком 1834 году. Из-за проблем с финансированием и отсутствием необходимых для постройки машины технологий построить ее в то время так и не удалось. Несмотря на этот факт, именно аналитическую машину считают первым созданным человеческим разумом автоматическим устройством для хранения и обработки математической информации, то есть первым компьютером.


Один из элементов аналитической машины, собранный сыном Бэббиджа после его смерти (фото Andrew Dunn)

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

Подобную архитектуру имеют все современные компьютеры, состоящие из арифметико-логического устройства (АЛУ), шины передачи данных, оперативной памяти и устройств ввода-вывода. Упрощенно взаимодействие этих элементов можно изобразить с помощью следующей схемы.

Архитектура компьютера

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

В информатике оперативную память принято также называть оперативным запоминающим устройством (ОЗУ), что более точно отображает суть этого элемента вычислительной машины.

Физическая реализация ОЗУ на разных этапах развития

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

Появление электромеханических вычислителей и первых электронно-вычислительных машин (ЭВМ) привело к созданию более быстрых и надежных методов хранения информации. На первых порах различные исследовательские центры весьма широко экспериментировали с конструкциями и физическими принципами работы запоминающих устройств. Были созданы ОЗУ, работающие на электромеханических реле, на электромагнитных переключателях, на электростатических трубках, на электронно-лучевых трубках. Затем появились различные варианты магнитных запоминающих устройств - магнитные диски и барабаны, в то время как длительное хранение информации осуществлялось на магнитных лентах. Диски и барабаны обеспечивали значительно меньшее время доступа к каждой ячейке данных по сравнению с лентами. А одним из основных требований, предъявляемых к оперативной памяти, было и остается по сей день высокое быстродействие.

Магнитный барабан (фото из «Википедии»)

Помимо магнитных дисков и барабанов длительное время в качестве быстрой памяти использовались массивы на ферромагнитных сердечниках, которые обеспечивали очень высокую скорость доступа. Основным недостатком подобных массивов была большая энергоемкость и весьма крупные габаритные размеры ОЗУ.

Элемент памяти на магнитных сердечниках конструкции К. Олсена (1964 г.)

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

Самый серьезный толчок развитию ЭВМ дало создание БИС (больших интегральных схем), состоящих из большого числа полупроводниковых транзисторов, заключенных в один корпус. Скорость обработки информации увеличилась настолько, что быстродействия существовавшей на то время оперативной памяти катастрофически не хватало для обеспечения нормальной работы компьютеров в целом. Понадобилось разработать принципиально новые методы хранения информации, которыми мы пользуемся и до сих пор.

Строение и принцип работы современной оперативной памяти

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

Динамическая память

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

Принципиальная схема ячейки динамической памяти

Основное достоинство - дешевизна производства и малый размер каждой ячейки. Современная элементная база позволяет вмещать миллионы подобных пар на каждый квадратный миллиметр микросхемы памяти.

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

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

Еще одним неприятным свойством любого конденсатора является его электрическая инерционность. Изменение емкости не является мгновенным процессом, следовательно, чтение единицы информации и ее перезапись занимают какое-то время, необходимое для накопления или сброса электрического заряда.

Статическая память

В триггерных системах памяти хранение каждого бита информации происходит в единичных триггерах, которые фактически представляют собой группы из шести-восьми транзисторов. Так как состояние триггера зависит исключительно от наличия управляющего сигнала и не меняется с течением времени (пока есть питающее напряжение), то такой тип памяти называют статической памятью. Основным достоинством статической ОЗУ является ее чрезвычайно высокое быстродействие, так как переключение триггера происходит практически мгновенно при подаче соответствующего управляющего сигнала на вход элемента.

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

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

Вместо вывода

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

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

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

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

В этой статье:

  • Определение переменных
  • Переменные командной строки (параметры вызова bat-файла)
  • Оператор условия IF
  • Функции
  • Использование возвращаемых значений (обработка кода завершения программы)

Определение переменных

SET <Имяпеременной>=<Значениепеременной>

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

SET BLASTER=A220 I5 D1 P330

то при использовании в пакетном файле следующей конструкции:

ECHO %BLASTER%

на экран будет выведено "A220 I5 D1 P330". Переменные, определенные с помощью оператора SET называются переменными окружения среды (environment) и являются видимыми после выполнения до перезапуска DOS (если не изменять ее вручную в памяти). То есть, ее можно использовать из одного пакетного файла или программы после задания в другом. Наиболее известной является переменная PATH, представляющая собой набор путей для быстрого поиска файлов. Она задается в файле autoexec.bat.

Переменные командной строки
(параметры вызова bat-файла)

%<цифра 0-9>

Как и в любом языке, в языке пакетных файлов возможно использование переменных, полученных в качестве параметров bat-файла.

Всего может быть 10 одновременно существующих независимых переменных. Для написания сложных программ это довольно мало, хотя для обычной работы часто хватает и 3-4. Значение переменной равно значению соответствующего параметра из командной строки. Переменная %0 будет содержать имя.bat-файла и, если вы указали, путь к нему. То есть, если вы запустили файл abc.bat со следующими параметрами:

abc.bat a bc def

то переменная %0 будет содержать значение abc.bat , %1 будет содержать значение a, %2 будет содержать bc , а %3 - def . Это свойство широко используется для создания универсальных пакетных файлов при работе с повторяющимися операциями.

Чтобы получить более чем 10 переменных из командной строки, можно воспользоваться командой SHIFT .

Команда SHIFT позволяет использовать число параметров командной строки далее 10. Однако, при этом теряются соответственно более ранние параметры. Иными словами, команда SHIFT сдвигает все значения переменных на один шаг влево. То есть, переменная %0 будет содержать значение, содержавшееся до этого в переменной %1 , а переменная %1 - значение переменной %2 до сдвига. Однако, данная операция является необратимой, то есть, невозможно сдвинуть переменные обратно.

Оператор условия IF

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

if condition (

Rem Команды ветки ‘then’

Rem ...

) else (

Rem Команды ветки ‘else’

Rem ...

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

@echo off

set BUILDMODE=%1

if "%BUILDMODE%" == "" (

Echo FAIL: Аргумент является обязательным ^(--debug, --release^)

Exit /b 1

rem Удаляем из аргумента все дефисы для упрощения обработки

set BUILDMODE=%BUILDMODE:-=%

if "%BUILDMODE%" == "debug" (

Set CCFLAGS=/Od /MDd /Z7

) else (

Set CCFLAGS=/O2 /MD

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

if "%BUILDMODE%" == "debug" (

Echo INFO: Устанавливаем debug-режим окружения

Set OPTFLAGS=/Od

Set CCFLAGS=%OPTFLAGS% /MDd /Z7

) else (

Echo INFO: Устанавливаем release-режим окружения

Set OPTFLAGS=/O2

Set CCFLAGS=%OPTFLAGS% /MD

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

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

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

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

setlocal enabledelayedexpansion

if "%BUILDMODE%" == "debug" (

Echo INFO: Setting up debug mode environment

Set OPTFLAGS=/Od

Set CCFLAGS=!OPTFLAGS! /MDd /Z7

) else (

Echo INFO: Setting up release mode environment

Set OPTFLAGS=/O2

Set CCFLAGS=!OPTFLAGS! /MD

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

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

Функции

А можно создать в bat-файле функцию? Да, можно. Более того, иногда даже нужно. Правда, функциями это можно назвать условно.

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

call:метка аргументы

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

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

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

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

call /?

exit /?

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

@echo off

call:factorial %1

echo %RESULT%

exit

rem Функция для подсчета значения факториала

rem Вход:

rem %1 Число, для которого необходимо подсчитать факториал

rem Выход:

rem %RESULT% Значение факториала

:factorial

if %1 == 0 (

Set RESULT=1

Exit /b

if %1 == 1 (

Set RESULT=1

Exit /b

set /a PARAM=%1 - 1

call:factorial %PARAM%

set /a RESULT=%1 * %RESULT%

exit /b

Пример работы:

> factorial.bat 10

3628800

Использование возвращаемых значений
(обработка кода завершения программы)

Любая программа при завершении своей работы возвращает операционной системе код своего завершения. Принято при успешном завершении возвращать ноль, иначе - код ошибки. Иногда, или, вернее, часто, программа "сознательно" возвращает ненулевое значение для того, чтобы в пакетном файле можно было "узнать" некоторые подробности ее работы. Например, программа возвращает код нажатой клавиши, а.bat-файл по нему выполняет различные действия.

Каким же образом пакетный файл может узнать код завершения выполненной программы? Для этого предусмотрено ключевая переменная ERRORLEVEL .

Пример пакетного файла с errorlevel"ами:

@ECHO OFF

REM Запускаем программу prg1.exe

PRG1.EXE

REM Анализ кода завершения

IF ERRORLEVEL 2 GOTO FILENOTFOUND

IF ERRORLEVEL 1 GOTO WRITEERROR

IF ERRORLEVEL 0 GOTO EXITOK

GOTO ONEXIT

:FILENOTFOUND

ECHO Ошибка! Файл не найден!

GOTO ONEXIT

:WRITEERROR

ECHO Ошибка записи!

GOTO ONEXIT

:EXITOK

ECHO Программа завершена благополучно.

GOTO ONEXIT

:ONEXIT

Обратите внимание - анализ кода завершения начинается не с нуля, а с максимально возможного значения. Дело в том, что подобная проверка означает: "если errorlevel больше или равен значению, то...". То есть, если мы будем проверять, начиная с нуля, любое значение будет истинным на первой же строке, что неверно.

Это самая распространенная ошибка в подобного рода программах.

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

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

Существуют некоторые стандарты кодирования, которые говорят: если вы пишете оператор if , вы должны использовать фигурные скобки, даже если у вас нет предложения else . Это избавляет вас от тонких, трудно отлаживаемых проблем и недвусмысленно читается. Я не вижу причин, по которым вы не могли применить это рассуждение к пакетным файлам.

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

IF EXIST somefile.txt IF EXIST someotherfile.txt SET var=somefile.txt,someotherfile.txt

И синтаксис if , из команды HELP IF:

IF ERRORLEVEL number command IF string1==string2 command IF EXISTS filename command ... IF EXIST filename (command) ELSE (other command)

Итак, вы цепляете if как команды.

Если вы используете стандартное правило стандартного кодирования, о котором я упоминал выше, вы всегда хотели бы использовать parens. Вот как вы могли бы сделать это для своего примера кода:

IF EXIST "somefile.txt" (IF EXIST "someotherfile.txt" (SET var="somefile.txt,someotherfile.txt"))

Удостоверьтесь, что вы четко форматируете и выполняете какую-то форму отступа. Вы делаете это в коде, и вы должны делать это в своих пакетных сценариях.

Кроме того, вы также должны иметь привычку всегда ссылаться на ваши имена файлов и получать право на цитаты. Существует несколько слов в HELP FOR и HELP SET , которые помогут вам удалить лишние кавычки при повторном цитировании строк.

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

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

В этой статье мы рассмотрим условный оператор if командной строки (CMD). Как и в любом другом языке программирования, условные оператор служит для проверки заданного условия и в зависимости от результат, выполнять то, или иное действие.

Условный оператор cmd if содержит практически тот же синтаксис, что и аналогичные конструкции языков VBScript (смотри статью “ ”) и Jscript (статья “ ”) сервера сценариев .

Оператор if командная строка

if условие (оператор1)

Вначале идет проверка условия, если оно выполняется, идет переход к выполнению оператора1, если нет – к оператору2. Если после ключевого слова if прописать not (if not) , то: произойдет проверка условия, если оно не выполниться – переход к оператору1, если условие выполняется – переход к оператору2. Использование круглых скобок не является обязательным, но если вам нужно после проверки условия выполнить сразу несколько операторов cmd if, то круглые скобки необходимы.

Давайте откроем редактор notepad++ и пропишем в нем такой код:

Тут, как и прежде идет проверка передаваемого сценарию параметра, если значение равно 1, то произойдет последовательное выполнение трех команд:

  • hostname – выводит имя компьютера
  • ver – выводит версию ОС
  • ipconfig /all – выводит настройки сети

Для последовательного выполнения команд мы использовали знак конкатенации (объединения) “&”. При невыполнении условия произойдет вызов утилиты netstat .

Что бы проверить существование переменной, используются операторы if defined (если переменная существует) и if not defined (если переменная не существует):

@ echo off set Var1 =100 if defined Var1 (echo % Var1% ) set Var1 = if not defined Var1 (echo NOT EXIST!!! Var1)

Если вы запустите на выполнение данный код, то в окне командной строки будут выведены две строки:

100
NOT EXIST!!! Var1

Вначале, в сценарии происходит создание переменной Var1 и присвоение ей значения 100, далее идет проверка: если переменная Var1 существует, вывести ее значение. Потом мы удаляем переменную и снова запускаем проверку: если переменная Var1 не существует, вывести строку NOT EXIST!!! Var1.

Мы вправе использовать условный оператор if как вложенный:

@ echo off if "%1" =="1" (@ if "%2" =="2" (hostname & ver) else (ver) ) else (hostname & ver & netstat -a)

В данном примере, первый оператор командной строки if проверяет, равен ли первый аргумент 1, если да, то идет выполнение второго условно оператора и проверка на значение другого аргумента.

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

Давайте теперь посмотрим на такой пример:

В данном случае, передадим мы строку SLOVO, slovo, SloVo и так далее, все ровно на экран консоли выведется строка “slovo”, так как учет регистра знаков будет отключен.

Оператор if командная строка, операторы сравнения

Кроме оператора сравнения “==” можно использовать и другие операторы для проверки условия:

  • equ «Равно». Дает True, если значения равны
  • neq «Не равно». Дает True, если значения не равны
  • lss «Меньше». Дает True, если зпачение1 меньше, чем значение2
  • lcq «Меньше или равно». Дает True, если значепие1 равно или меньше, чемзначение2
  • gtr «Больше». Дает True, если значение1 больше, чем значение2
  • geq «Больше или равно». Дает True, если значепие1 равно или больше, чем значение2

В этой статье мы рассмотрели условный оператор командной строки if.



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: