1 (изменено: Rumata, 2020-12-16 12:58:04)

Тема: CMD/BAT: Условные операторы на стероидах

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

В основу улучшений легла встроенная функция test из unix shell. Именно они и были названы "стероидами".

Не все условные выражения test реализованы. Некоторые и них работают только при определенных условиях. Было добавлено несколько собственных решений.

В процесе разработки строго соблюдалось правило - использовать только внутренние команды интерпретатора CMD.EXE. Следование этому правилу не повлияло на реализацию условных выражений.

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

Ссылка на скачивание
К сожалению, лаконично писать я не умею, поэтому помещаю ссылку поближе к началу, чтобы она не затерялась и заинтересованные могли ее быстро найти.
https://github.com/ildar-shaimordanov/c … r/when.bat

Стандартный оператор IF
Стандарная форма условного оператора весьма ограничена.


if EXPR (
    DO_THEN
) else (
    DO_ELSE
)

Она фактически не умеет вычислять более сложные логические выражения вида EXPR1 and EXPR2 ... или EXPR1 or EXPR2 .... В общем случае это либо классические решения с использованием меток, либо сокращенные версии вида if EXPR1 if EXPR2 DO_THEN.

Есть несколько случаев, когда простая проверка реализована в виде громоздкой конструкции с использованием циклов (проверка атрибутов или свойств файла). Данное решение скрывает эти недостатки и делает все условные проверки единообразными.

Условный оператор на "стероидах"
Общая форма "стероидов":


call when :if EXPR && DO_THEN

Основа - стрипт when.bat. Он содержит две "функции" (функция - в терминах пакетных скриптов). :if вычисляет условное выражение и возвращает (0), если выражение верно, иначе (1). Возвращает код (2), в случае неправильных аргументов.

:unless аналогично :if, но смысл проверки противоположен.

Аналогично встроенной команде IF функция вычисляет одно простое логческое выражение. Но, благодаря тому, что они возвращают статус их можно объединять в более сложные команды, эмулируя тем самым составные логические выражения. Следующие примеры несколько искусственные, но они иллюстрируют сказанное:


:: if "%PROCESSOR_ARCHITEW6432%" != "" && "%PROCESSOR_ARCHITECTURE%" == "x86" (
:: )
(
    call when :if -n "%PROCESSOR_ARCHITEW6432%" && call test :if "%PROCESSOR_ARCHITECTURE%" == "x86" 
) && (
    echo режим эмуляции
)

:: if "%PROCESSOR_ARCHITEW6432%" == "AMD64" || "%PROCESSOR_ARCHITEW6432%" == "IA64" && "%PROCESSOR_ARCHITECTURE%" == "x86" (
:: )
(
    call when :if "%PROCESSOR_ARCHITEW6432%" == "AMD64" || call test :if "%PROCESSOR_ARCHITEW6432%" == "IA64"
) && (
    call when :if "%PROCESSOR_ARCHITECTURE%" == "x86" 
) && (
    echo режим эмуляции
)

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

Благодаря тому, что используется статус завершения (0 или 1) эти команды можно комбинировать с другими командами, реализуя достаточно сложные условные проверки.

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

Чтобы встроить и использовать его в своих скриптах без вызова внешнего скрипта достаточно выполнить следующую команду, которая встроит тело скрипта в основной (в примере filename):


call when APPEND-TO filename

После этого функции :if и :unless будут доступны напрямую, по метке, без вызова внешноего скрипта:


(
    call :if -n "%PROCESSOR_ARCHITEW6432%" && call :if "%PROCESSOR_ARCHITECTURE%" == "x86" 
) && (
    echo режим эмуляции
)

Расширенные файловые операторы

-a FILE
Верно, если файл существует.

-b FILE
Верно, если аргумент - дисковое устройство.

-c FILE
Верно, если аргумент - символьное устройство.

-d FILE
Верно, если аргумент - каталог. Аналогично -attr d.

-e FILE
Верно, если файл существует.

-f FILE
Верно, если аргумент - обычный файл.

-h FILE
Верно, если аргумент - ссылка. Аналогично -attr l.

-L FILE
Верно, если аргумент - ссылка. Аналогично -attr l.

-r FILE
Верно, если файл имеет атрибут только чтение. Аналогично -attr r.

-s FILE
Верно, если файл существует и непустой.

-w FILE
Верно, если файл доступен на запись, например, не установлен атрибут только чтение.

-x FILE
Верно, если файл исполнимый.

-attr ATTR FILE
Верно, если установлен атрибут файла.

Доступные следующие атрибуты:


    Attribute                    Expansion
    FILE_ATTRIBUTE_DIRECTORY     d--------
    FILE_ATTRIBUTE_READONLY      -r-------
    FILE_ATTRIBUTE_ARCHIVE       --a------
    FILE_ATTRIBUTE_HIDDEN        ---h-----
    FILE_ATTRIBUTE_SYSTEM        ----s----
    FILE_ATTRIBUTE_COMPRESSED    -----c---
    FILE_ATTRIBUTE_OFFLINE       ------o--
    FILE_ATTRIBUTE_TEMPORARY     -------t-
    FILE_ATTRIBUTE_REPARSE_POINT --------l
    FILE_ATTRIBUTE_NORMAL        ---------

-path FILE
Верно, если файл есть в одном из каталогов переменной окружения PATH.

Еще файловых операторов

FILE1 -nt FILE2
Верно, если FILE1 новее чем FILE2 (в соответствии с временем модификации файла). Этот оператор зависит от пользовательских и региональных настроек. Это значит, что в общем случае, сравнение не может быть надежным.

FILE1 -ot FILE2
Верно, если FILE1 старее чем FILE2 (в соответствии с временем модификации файла). Этот оператор зависит от пользовательских и региональных настроек. Это значит, что в общем случае, сравнение не может быть надежным.

Расширенные строковые операторы

-n STRING
Верно, если строка непустая.

-z STRING
Верно, если строка пустая.

Еще строковых операторов

STACK -contains NEEDLE
Верно, если STACK содержит NEEDLE.

STACK -starts NEEDLE
Верно, если STACK начинается с NEEDLE.

STACK -ends NEEDLE
Вернл, если STACK завершается NEEDLE.

( 2 * b ) || ! ( 2 * b )

2

Re: CMD/BAT: Условные операторы на стероидах

Доброго дня. Тема очень интересна (для меня по крайней мере).
Но ссылка на скачивание нерабочая.
Есть альтернатива ?

3

Re: CMD/BAT: Условные операторы на стероидах

ydscher
https://github.com/ildar-shaimordanov/m … r/cmd/when

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

4

Re: CMD/BAT: Условные операторы на стероидах

ок! Спасибо.