Batch-script

Word of advice: When PATH doesn’t seem to be working (recent updates not showing) there is no harm in restarting, and it often fixes the issue.

  • Overview
  • Part 1 – Getting Started
  • Part 2 – Variables
  • Part 3 – Return Codes
  • Part 4 – stdin, stdout, stderr
  • Part 5 – If/Then Conditionals
  • Part 6 – Loops
  • Part 7 – Functions
  • Part 8 – Parsing Input
  • Part 9 – Logging
  • Part 10 – Advanced Tricks

Today we’ll cover variables, which are going to be necessary in any non-trivial batch programs. The syntax for variables can be a bit odd,
so it will help to be able to understand a variable and how it’s being used.

Основные команды

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

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

Batch-script

Copying to the Clipboard

You can use CLIP to copy anything to the clipboard. For example,

Unicode Issues with CLIP

The windows terminal has notorious issues with codepoints above the standard ascii range (e.g. emoji).

Verifying Checksums

A built in utility that you can use is CertUtil.

-hashfile my_program.exe SHA256

If you are looking for a GUI approach, check out hashcheck. Or this list of Windows freeware hash programs.

Since CertUtil can only hash files (not piped or stored strings), to check an online file (via cURL), clipboard contents, or any other strings, you would need to temporary save to a file and then pass the file to CertUtil.

-hashfile temp SHA256

🚨 WARNING: Be really wary of how easy it is to accidentally add or include newlines and/or extra spacing in the content you are trying to generate a hash from. If you accidentally add one in the shell that is not present in the content, the hashes won’t match.

If you want to quickly hash / encode strings with a GUI, I highly recommend the CyberChef online tool. Here is an example recipe for SHA256+Base64.

Capturing Output to Variable

The popular “trick” seems to be to use:

For details see:

Передача параметров командному файлу.

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

params.bat FIRST second “two words”
Параметры командной строки, содержащие пробелы должны заключаться в двойные кавычки.

При обработке входных параметров необходимо знать, были ли они вообще заданы в командной строке. Для проверки наличия каких-либо входных параметров, передаваемых
командному файлу, можно проверить, является ли значение переменной %1
пустым, что можно сделать, заключив ее, например в двойные кавычки, и проверив полученный результат на наличие этих кавычек, следующих подряд:

REM пробел текст
Строки, начинающиеся с REM пробел, считаются комментариями и командным процессором игнорируются.

Использование переменных окружения в командных файлах.

При работе с командными файлами невозможно обойтись без переменных окружения (environments) – переменных, значения которых определяют среду, в которой выполняются команда или пакетный файл. Часто их называют переменными среды. Значения, принимаемые этими переменными формируются при
загрузке Windows, регистрации пользователя в системе, старте или завершении
некоторых приложений, и, кроме того, могут быть заданы с помощью специальной
команды
SET переменная = значение

SETX переменная = значение

Первая присваивает значение переменной, действующее до завершения текущей сессии командной строки. Вторая – значение, действующее постоянно.

Как уже упоминалось выше, значение, присвоенное какой-либо переменной, доступно для обработки в командной строке или в командном файле с использованием ее имени, заключенного в знаки процента – % . Системные переменные позволяют получить сведения об аппаратной и программной среде, в которой выполняется командный файл, что позволяет реализовать его исполнение на разных компьютерах, независимо от их конкретной конфигурации и пользовательских настроек. Например, в командном файле используется вывод содержимого системного каталога C:Windows :

DIR C:Windows

Алгоритм, реализуемый данным командным файлом, будет прекрасно выполняться до тех пор пока не встретится компьютер с Windows установленной не на диск C:, а например, на D:. Чтобы этого не происходило, желательно использовать системную переменную WINDIR, принимающую значение пути системного каталога:

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

SET PATH=C:Windows; C:windowssystem32
Данная команда определяет, что поиск исполняемых файлов будет выполняться в
каталоге C:Windows и, если результат неуспешен, в
C:windowssystem32

При необходимости выполнить программу, например, myedit.exe, размещенную в
каталоге C:NewProgs необходимо либо указать полный путь исполняемого файла, либо сделать текущим каталогом каталог с программой и использовать только его имя. Если в командной строке не задан полный путь, а только имя
исполняемого файла – myedit.exe

то сначала будет выполняться поиск файла myedit.exe в текущем каталоге, и если
он не будет найден – в каталогах, список которых определяется значением переменной
PATH. Символ ; является разделителем элементов в списке путей поиска.
Если в приведенном примере, текущим каталогом не является
C:NewProgs, и в остальных каталогах, заданных значением переменной
PATH, нет исполняемого файла myedit.exe, то попытка его запуска
завершится ошибкой. Однако, если модифицировать значение переменной PATH, добавив в нее требующийся каталог, то указание полного пути исполняемого файла становится необязательным.
Команда

изменит текущее значение PATH,
добавив каталог C:NewProgs в начало списка. Для добавления каталога в конец списка используется несколько иная конструкция:

SET PATH=%path%; C:NewProgs

Выполнение команды SET без параметров позволяет получить текущие
значения переменных окружения:

NUMBER_OF_PROCESSORS=1 – количество процессоров

OS=Windows_NT- тип ОС

Path=C:WINDOWSsystem32; C:WINDOWS;C:Program FilesFar – путь поиска исполняемых файлов.

PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE; .JS;.JSE;.WSF;.WSH – расширения для исполняемых файлов.

PROCESSOR_ARCHITECTURE=x86 – архитектура процессора.

PROCESSOR_IDENTIFIER=x86 Family 6 Model 8 Stepping 1, AuthenticAMD – идентификатор процессора.

PROCESSOR_LEVEL=6 – уровень (номер модели) процессора.

PROCESSOR_REVISION =0801 – версия процессора.

ProgramFiles=C:Program Files – путь к папке “Program Files”

SystemDrive=C: – буква системного диска.

SystemRoot= C:WINDOWS – каталог ОС Windows.

Значения некоторых переменных по команде SET не отображаются, хотя и присутствуют в системе. В основном, это переменные, принимаемые значения которых динамически изменяются:

%CD% – Принимает значение строки текущего каталога.

%DATE% – Принимает значение текущей даты.

%TIME% – Принимает значение текущего времени.

%RANDOM% – Принимает значение случайного десятичного числа в диапазоне 1 -32767.

%ERRORLEVEL% – Принимает текущее значение кода завершения задачи ERRORLEVEL

%CMDEXTVERSION% – Принимает значение версии командного процессора CMD.EXE для расширенной обработки команд.

%CMDCMDLINE% – Принимает значение строки, которая вызвала
командный процессор.

Значения, принимаемые переменными окружения, могут быть расширены с помощью
специального признака – символа ” ~ “, что позволяет получить их частичное
значение, или изменить его подменой какой-либо части. Практические примеры использования расширений переменных будут рассмотрены ниже.

Подробное описание команд с примерами их использования имеется в разделе Список команд CMD Windows.

How to get system and user vars

  • PATH
  • can be accessed just by using %varName% syntax

Using variables

WARNING: Be careful about wrapping variables in quotes; you can end up accidentally nesting quotes / double quoting.

If you are trying to use a path directly to access contents (for example, with in (filename.txt), you won’t want quotes around the string)

Variable Declaration

DOS does not require declaration of variables. The value of undeclared/uninitialized variables is an empty string, or “”. Most people like this, as
it reduces the amount of code to write. Personally, I’d like the option to require a variable is declared before it’s used, as this catches
silly bugs like typos in variable names.

Listing Existing Variables

The SET command with no arguments will list all variables for the current command prompt session. Most of these varaiables will be system-wide environmental variables, like %PATH% or %TEMP%.

Batch-script

NOTE: Calling SET will list all regular (static) variables for the current session. This listing excludes the dynamic environmental variables like %DATE% or %CD%. You can list these dynamic variables by viewing the end of the help text for SET, invoked by calling SET /?

Variable Assignment

The SET command assigns a value to a variable.

NOTE: Do not use whitespace between the name and value; SET foo = bar will not work but SET foo=bar will work.

SET /A four=2+2
4

A common convention is to use lowercase names for your script’s variables. System-wide variables, known as environmental variables, use uppercase names. These environmental describe where to find certain things in your system, such as %TEMP% which is path for temporary files. DOS is case insensitive, so this convention isn’t enforced but it’s a good idea to make your script’s easier to read and troubleshoot.

Переменные

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

Для добавления переменной существует команда set. Чтобы объявить переменную, необходимо написать в строке set, а затем ее имя и значение. Если необходимо обратиться к переменной и считать ее значение, то к имени переменной слева и справа добавляется символ %. Приведем ниже пример:

:/>  Как разогнать монитор до 75 Герц и выше на видеокартах Intel, AMD, NVIDIA

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

Batch-script

Также, при объявлении переменной можно воспользоваться флагом /a, который отвечает за присваивание переменной числа. Например:

При отсутствии такого флага, переменной присваивается вся строка после знака равенства. Результат представленной выше программы продемонстрирован на картинке:

Batch-script

Кроме обычных переменных существуют переменные аргумента. Данным переменным присваиваются значения, которые передаются в момент вывоза bat-файла. Выглядят они следующим образом: %1, %2, %3 и т.д.

Приведем пример для лучшего понимания:

Batch-script

Symlinking

On Win, you can use MKLink (ss64) to create a symlink to a directory or file.

In general, it is best / easiest to always use absolute paths for the targets. You might want to wrap paths in quotes if you are having issues.

Removing Quotes from String Variables

To remove quotes from a variable, use set VAR_NAME=%VAR_NAME:”=% (ref)

You can also avoid quoted variables by enclosing the entire set command in quotes when declaring it:

ELSE IF

Unfortunately, there is no built-in command for reading from the clipboard in Windows, at least in command prompt. There is a tool built-in to PowerShell though; Get-Clipboard.

If you really need this functionality in CMD, you can always execute the Powershell command from command prompt:

-command
REM # Can pipe or redirect as you please
REM # Example: print clipboard to stdout

Copy files

There are a bunch of built-in tools. In order of online recommendations:

  • ss64
  • This S/O covers the defaults for which files Robocopy will skip copying; you can use /IT to included tweaked files, and /IS to include same files
  • Use /l to perform a dry-run / preview what would happen
  • XCopy
  • Copy

File permissions

You can use TAKEOWN to take ownership of files.

REM # Folder contents is foo.txt and subfolder ./pics.
REM # We need to take ownership of ./pics
pics

Launching Applications

REMINDER – even though there is no wildcard at the ends, it still acts like one for some reason. So DEL /S *.qml will delete all .qml files, but also all .qmlc files – see https://stackoverflow.com/a/32399927

NOTE – Powershell does not suffer from the above issue – .qml will match .qml and not .qmlc

Специальные символы CMD

Работа с командным процессором предполагает использование двух стандартных устройств – устройства ввода (клавиатура) и устройства вывода (дисплей). Однако, имеется возможность изменить стандартно используемые устройства ввода-вывода с помощью специальных символов – символов перенаправления

– перенаправление вывода
– перенаправление ввода

Для вывода справки не на экран а, например, в файл с именем help.txt, можно использовать следующую команду:

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

cmd.exe < commands.txt – командный процессор не будет ожидать ввода команд с клавиатуры, а считает их из файла commands.txt. Фактически, указанный текстовый файл в данном случае является командным файлом.

При запуске командного процессора можно указать конкретную команду в качестве аргумента командной строки:

cmd.exe /C HELP FOR – выполнить команду HELP FOR и завершиться (параметр командной строки или ключ /C)

cmd.exe /K HELP FOR – выполнить команду HELP FOR и перейти в режим ожидания дальнейшего ввода команд (ключ /K)

Подробную справку по использованию cmd.exe можно получить, введя в качестве аргумента ключ /?

& – одиночный амперсанд используется для разделения нескольких команд в одной командной строке.

команда1 & команда2 – выполняется первая команда, затем вторая команда.

&& – удвоенный амперсанд между двумя командами, означающий условное выполнение второй команды. Она будет выполнена, если код завершения (или код возврата) первой команды равен нулю, т.е. команда выполнена успешно. Успешность
выполнения команды определяется значением специальной переменной среды ERRORLEVEL.

команда1 && команда2 – выполняется команда1, а команда2 выполняется, только если первая была выполнена успешно.

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

cmd.exe /C “HELP IF” & ”HELP IF”

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

“”HELP” не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.

Как и в любом другом языке программирования, в сценариях CMD невозможно обойтись без переменных. Для получения их значения применяется специальный символ – знак процента % . Строка, заключенная в знаки процента интерпретируется как значение переменной, например:

Символ ^ , являющийся последним символом строки, используется как признак продолжения предыдущей. Это относится как к тексту, так и к командам.

Удаление ненужных файлов

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

Например, у пользователя во время работы появляется много файлов с расширением .txt в некотором каталоге и его подкаталогах, которые необходимо подчистить. Реализуем для этого случая простой «батник»:

Разберем работу каждого флага:

  • /f — данный флаг позволяет удалять все возможные файлы (даже те, что открыты только для чтения).
  • /s — флаг позволяет удалять файлы не только из каталога, но и его подкаталогах.
  • /q — данный флаг убирает подтверждение удаления файлов.

Теперь создадим каталог Example и подкаталог ExampleWithTXT, а после добавим и в первый, и во второй файлы с расширением .txt, чтобы проверить работоспособность созданного выше «батника»:

mkdir Examplecd Examplemkdir ExampleWithTXTnotepad Example1.txtnotepad Example2.txtnotepad Example3.txtcd ExampleWithTXTcopy C:путь_к_каталогуExample*.txt

После выполнения всех команд будет создан тестовый каталог Example с тремя текстовыми файлами и подкаталогом ExampleWithTXT. В последний были скопированы три текстовых файла из родительского каталога.

Batch-script

Теперь запустим bat-файл и посмотрим на результат. Он будет представлен на картинке ниже.

Batch-script

Все файлы с расширением .txt были успешно удалены из каталога Example и подкаталога ExampleWithTXT.

Создание архива, имя которого содержит дату и время.

Решим следующую задачу – нужно создать архив файлов, находящихся в каталоге
C:Program FilesFAR. Имя архивного файла должно состоять из текущего времени
(часы.минуты.секунды – ЧЧ.ММ.СС.rar), и помещен он должен в новый каталог, имя которого должно состоять из текущей даты
(день.месяц.год – ДД.ММ.ГГГГ). Для архивирования будем использовать архиватор RAR.
Формат запуска для создания архива:

a – команда создания архива.
-r – ключ, определяющий архивирование подкаталогов (т.к. в исходной папке есть подкаталоги).

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

Converting Paths to Forward Slashed

If you have git-bash, or something like that which includes the sed program, that is a fast solution:

Using the current directory you are in as a variable

  • Works great for opening current folder with various programs
    “C:Program FilesMicrosoft VS CodeCode.exe” %cd%Explorer.exe %cd%
  • “C:Program FilesMicrosoft VS CodeCode.exe” %cd%
  • Explorer.exe %cd%

Active Connections, Ports, Etc

The go-to command for listing active connections and listening ports is netstat.

Keeping file open after execution

Add this to very end of file:

Reading the Value of a Variable

In most situations you can read the value of a variable by prefixing and postfixing the variable name with the % operator. The example below prints the current value of the variable foo to the console output.

There are some special situations in which variables do not use this % syntax. We’ll discuss these special cases later in this series.

List file tree

  • For both files and folders
    tree /F
  • tree /F

Tasklist

  • Find process by exe name
    tasklist /FI “IMAGENAME eq Greenshot.exe”
  • tasklist /FI “IMAGENAME eq Greenshot.exe”
  • Optional: /F for “force”

Passing Input Arguments to Another Program

If you need to pass trailing input arguments to another program, you can use %*.

For example, if I wanted to create a stub file in a in folder that simply calls another, I could do something like this:

By the way, this is how NodeJS handles cmd files in the .bin folder – they use this syntax to call node your-file.js your-args.

Removing Line Breaks from Strings

Similar to the above approach for removing quotes, you can use the string manipulation syntax to replace line breaks with nothing, thus removing them.

Credit to this S/O

Removing Trailing Line Breaks and Empty Lines – Set

Removing a trailing empty line is, like many things in CMD, not as simple as many of us would like.

If you are looking for completely native option and have not yet saved or captured the output, the agreed upon method seems to be to use set /p (credit to S/O):

# This even works with variables

Variable Scope (Global vs Local)

By default, variables are global to your entire command prompt session. Call the SETLOCAL command to make variables local to the scope of your script. After calling SETLOCAL, any variable assignments revert upon calling ENDLOCAL, calling EXIT, or when execution reaches the end of file (EOF) in your script.

This example demonstrates changing an existing variable named foo within a script named HelloWorld.cmd. The shell restores the original value of %foo% when HelloWorld.cmd exits.

:/>  Простой калькулятор онлайн ✔ Самые точные расчеты по правилам!

Batch-script

A real life example might be a script that modifies the system-wide %PATH% environmental variable, which is the list of directories to search for a command when executing a command.

Batch-script

Handy Commands for Exploring an OS

systeminfo
Displays a bunch of system information, including OS version, PC model, uptime, and more.

List all files by size (recursive subdir too)

Строки командных файлов могут содержать как команды самого
процессора команд CMD, так и имена исполняемых модулей (программ или командных файлов).

– исполняемый файл ping.exe с параметром yandex.ru. Расширение .exe можно не указывать, и данная команда может быть записана так:

Список стандартных команд можно получить, введя команду:

Справочную информацию по конкретной команде можно получить, указав ее название в качестве параметра команды HELP:

HELP Имя команды

В русифицированной версии Windows необходимо учитывать, что в среде командного процессора символы национального алфавита отображаются в DOS-кодировке, в соответствии с кодовой страницей (code page) 866. При необходимости, для переключения между кодовыми страницами Windows и DOS используется команда

CHCP номер страницы
– использовать кодовую страницу 866 (DOS)
– использовать кодовую страницу 1251 (WINDOWS)

Внешний вид окна CMD.EXE (консоли Windows) можно изменить с помощью команды

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

– символы белого цвета на черном фоне (используется по умолчанию).

– черные символы на белом фоне.

– светло-желтые символы на черном фоне.

– подсказка для команды COLOR.

IF / Else

Make sure logic switches are on same line – https://ss64.com/nt/else.html

This Won’t work:

This should work:

Output text to file

Использование утилит командной строки и командных файлов нередко позволяют
решить многие проблемы связанные с повседневной эксплуатацией компьютерной
техники. Большинство системных администраторов и грамотных пользователей
продолжают ими пользоваться, несмотря на то, что в Windows проявилось новое,
более мощное и современное средство управления системой – WMI
(Windows Management Instrumentation) и многофункциональная оболочка пользователя Power Shell. Очевидно, не в последнюю очередь, это
обусловлено простотой реализации и достаточной
эффективностью командной строки для решения повседневных задач обслуживания системы.

Ниже приведены простые
примеры с комментариями, которые демонстрируют некоторые возможности и
способы применения .cmd и .bat

Joining string vars

Same as bash, you can just put them together:

And you can also put variables inside strings:

Environmental Variables

Use either the set command (temporary) or setx command (persisted).

variable – persists beyond current sessions

// System variable (global – requires elevated priv – persists beyond current sessions

// Temporary, takes effect in current session, does not persist

🚨 Notice that set has a different syntax than setx.

🚨 👉 SETX edits will only take effect in new console sessions, not the current one. See section below on refreshing environment variables.

“set” vs “setx”? Set is temporary – variable is set for duration of console session, whereas setx persists the value, even after you close the console.

Using Environmental Variables

Same syntax as using variables – %ENV_VAR_NAME%.

Example: cd %APPDATA%

🚨 👉 Environment variables, by default, cannot be used in a console that was spawned before their values were set. See below.

Refreshing Environment Variables

Environment variables, by default, cannot be read back in a console if they were set after the console was launched. E.g., if you launch two consoles and then call setx in one to set a value, neither of the two consoles can read back the value that was just set, and you would have to either restart each one to read the value, or spawn a new console (which is the same thing).

This a serious shortcoming of how environment variables work on Windows, but there are some workaround scripts, many good ones in the answers to this StackOverflow question.

Sadly, the best solution in many cases still, is to simply grab a fresh console.

Clearing Environment Variables

If the value was set via SET instead of SETX, then you could just spawn a new terminal instance to be in an environment with fresh value. If you want to clear a value set via setx, and/or don’t want to spawn a new terminal, the options to delete an environmental variable depend on what you want:

  • Deleting a variable for the current session:
    Use set with an empty assignment (no trailing space): set MYVAR=This will work for values set via SET, but will only work temporarily (current session) for those set via SETX
  • Use set with an empty assignment (no trailing space): set MYVAR=
  • This will work for values set via SET, but will only work temporarily (current session) for those set via SETX
  • System: REG delete “HKLMSYSTEMCurrentControlSetControlSession ManagerEnvironment” /F /V MYVAR
  • Kudos to this SO response

Automatically receiving calling input

In a .bat file, you can automatically receive and use the input that was provided when the file was called by using %1, %2, and so on.

There are multiple ways to handle errors in batch scripts.

Global Variables / Macros

This page has a comprehensive list of standard global environmental variables, and their default values. Also, lots of relevant tips for FOR variable syntax here.

Special Variables

There are a few special situations where variables work a bit differently. The arguments passed on the command line to your script are also variables, but, don’t use the %var% syntax. Rather, you read each argument using a single % with a digit 0-9, representing the ordinal position of the argument.
You’ll see this same style used later with a hack to create functions/subroutines in batch scripts.

Command Line Arguments to Your Script

NOTE: DOS does support more than 9 command line arguments, however, you cannot directly read the 10th argument of higher. This is because the special variable syntax doesn’t recognize %10 or higher. In fact, the shell reads %10 as postfix the %0 command line argument with the string “0”. Use the SHIFT command to pop the first argument from the list of arguments, which “shifts” all arguments one place to the left. For example, the the second argument shifts from position %2 to %1, which then exposes the 10th argument as %9. You will learn how to process a large number of arguments in a loop later in this series.

Tricks with Command Line Arguments

Command Line Arguments also support some really useful optional syntax to run quasi-macros on command line arguments that are file paths. These macros
are called variable substitution support and can resolve the path, timestamp, or size of file that is a command line argument. The documentation for
this super useful feature is a bit hard to find – run ‘FOR /?’ and page to the end of the output.

  • %~fI is the full path to the folder of the first command line argument
  • %~fsI is the same as above but the extra s option yields the DOS 8.3 short name path to the first command line argument (e.g., C:PROGRA~1 is
    usually the 8.3 short name variant of C:Program Files). This can be helpful when using third party scripts or programs that don’t handle spaces
    in file paths.
  • %~dpI is the full path to the parent folder of the first command line argument. I use this trick in nearly every batch file I write to determine
    where the script file itself lives. The syntax SET parent=%~dp0 will put the path of the folder for the script file in the variable %parent%.

Find executable paths

Use where to find files, as well as global executable / binary paths.

For example, where npm to find which NPM executables are globally registered in the path.

This is roughly equivalent to Unix’s / bash’s which command.

Asking for input

You can pause your script and ask for input by using this:

“What is your name? “

Evaluating symlinks

If you want to check what a symlink maps to (or just see if there are any in the current dir), you can use:

dir /a, or for just links, dir /aL

Присвоение съемному диску одной и той же буквы.

Задача заключается в том, чтобы съемный USB диск (флэш диск) был доступен
всегда под одной и той же буквой, независимо от того, на каком компьютере он
используется и каким образом он был подключен. Для ее решения воспользуемся уже упоминаемой выше командой SUBST, но реализуем присвоение новой буквы диску с
помощью подстановочного значения переменной %0, создаваемой
системой при каждом запуске командного файла.

Выберем для съемного диска желаемую букву, например – X.

Некоторые из переменных окружения, в том числе и переменная %0,
принимающая значение пути и имени выполняющегося командного файла, позволяют
при определенной модификации с использованием специального признака –
символа ” ~ “, получить ее частичное значение (расширение переменной).
Например, не полный путь
файла, а только его имя, или каталог расположения, или букву диска, с
которого он был запущен или еще около десятка различных элементов, связанных
с подстановочными значениями переменной %0.

:/>  Процент на компьютере клавиши

Дополнительное представление о подстановочных значениях
переменной %0 можно получить из командного файла следующего
содержания:

Комментирование

Для каждого комментария должна быть объявлена своя уникальная метка.

Creating Windows Shortcuts with Batch

Windows shortcut files (.lnk) are a very special proprietary file type, completely separate from symlinks. Their proprietary nature, and the fact that many programs open the target instead of the .lnk file itself, make them difficult to both edit and create.

There is essentially no built-in way to easily create shortcut files from the command line in Windows, especially in Win10. You can work around this with third-party utility programs, VB Scripts, or PowerShell.

My recommendation would be to use NirSoft’s NirCmd tool, and its shortcut command.

Синтаксис написания bat-файла

Ниже будут представлен список основных правил, которые нужно знать при написании bat-файла

  • Любая команда должна быть определена с новой строки.
  • Указанные в файле команды выполняются строго по порядку, от первого к последнему. Исключением являются те случаи, когда внутри файла организован переход от одной части к другой (например goto).
  • Чтобы исключить возможные ошибки, директории указываются в кавычках.
  • Возможно указывать два типа команд: встроенные и внешние. Первые — это команды самого интерпретатора командной строки (о них мы поговорим позже). Ко второму типу относятся все возможные исполняемые файлы (расширения .EXE, .CMD или .BAT).

Purposefully Including Line Breaks in Strings

Including line breaks in strings and variables is a little complicated with cmd / bat. There are multiple approaches, listed below in detail. For a good summary, this is a great S/O response.

Including Line Breaks – Using Echo

# The below line is actually a macro

# Notice how the below line does not use start

“MULTI_LINE_STR=Line One%NL%Line Two”

Including Line Breaks – Stored Variable with Delayed Expansion

# This is required for delayed expansion – makes escaping / using special chars easier
EnableDelayedExpansion enableextensions

# Special newline var

Do not remove this

# Notice use of wrapping quotes for escaping, plus expansion !
“MULTI_LINE_STR=Line One!NL!Line Two!”

# Even redirecting to a file works!

Above code based on this and this.

Including Line Breaks – Complex Escape Sequence

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

Исходные данные: имеется 2 съемных диска, один из которых должен быть виден в проводнике как диск X: , а второй – как диск Y: независимо от того, в какой порт USB они подключены и какие буквы присвоены им операционной системой. Для назначения букв дискам можно воспользоваться командой SUBST.
Будем считать, что реальные диски могут быть подключены как F: или G:
Опознавание дисков будем выполнять по наличию файла с определенным именем
(лучше всего такой файл сделать скрытым в корневом каталоге съемного диска и назвать его как-нибудь необычно):

Flashd1.let – на первом диске

Flashd2.let – на втором

Таким образом, задача командного файла заключается в том, чтобы проверить
наличие на сменных дисках F: и G: файлов Flashd1.let
или Flashd2.let и, в зависимости от того, какой из них присутствует,
присвоить диску букву X: или Y:

Для поиска файла на диске воспользуемся командой :

IF EXIST имя_файла команда

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

SUBST X: C: – – создать виртуальный диск
X:, содержимым которого будет корневой каталог диска C:

Для решения поставленной задачи, создаем командный файл, например с именем setletter.bat, следующего содержания:

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

При выполнении измененного таким образом командного файла, сообщение об
ошибке при выполнении SUBST исчезнет.

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

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

В качестве команды в строке командного файла можно использовать также
командный файл. Причем, для передачи с возвратом обратно к точке выполнения
вызывающего командного файла используется
команда CALL. Попробуйте создать командный файл test.bat, следующего содержания:

– приостановить выполнение командного файла до
нажатия любой клавиши.

Если же в файле test.bat убрать CALL, оставив “1.bat”, то , выполнится командный файл 1.bat, и возврат в test.bat выполняться не будет.

Вызываемый командный файл может создавать переменные и присваивать им
определенные значения, которые будут доступны для обработки в вызывающем
файле. Попробуйте изменить файл test.bat следующим образом:

Переменные вызываемого файла будут доступны в вызывающем файле.

Кстати, используя передачу управления командному файлу, можно организовать
его зацикливание. Попробуйте добавить в конец файла test.bat строку:

Выйти из зацикливания командного файла можно по нажатию комбинации
CTRL+Break.

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

Waiting for a process to finish in a batch script

Usually using the call command is the most reliable way to start a process or script and wait for it to finish:

Another option that sometimes works is using the start command, specifically with wait

💡 StackOverflow: CALL vs START /WAIT

More advanced example of START

Своя команда для создания новых файлов.

В составе операционной системы Windows нет специальной команды для создания нового файла, но без нее можно легко обойтись несколькими способами:

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

COPY CON myfile.txt

При выполнении этой команды данные с клавиатуры (стандартное устройство CON – консоль) будут заноситься в файл myfile.txt текущего каталога. Нажатие клавиши F6 или комбинации CTRL-Z завершит вывод.

Комбинация перенаправления ввода и перенаправления вывода:

При выполнении этой команды, как и в первом случае, используется копирование
с консоли в файл, но вместо ручного ввода данных с клавиатуры используется ввод с
несуществующего файла (устройства) xyz. Система выдаст сообщение, о том, что такого
устройства или файла
не существует, но пустой файл myfile.txt будет успешно создан.

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

COPY NUL myfile.txt

При работе в командной строке часто приходится создавать новые пустые
файлы, поэтому, стоит подготовить свой командный файл (например, с
именем nf.bat),

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

Для удобства использования, можно поместить этот командный файл в системный каталог
(например, в C:windowssystem32) или любой другой, существующий в путях
поиска, задаваемых значением переменной PATH). Теперь, в командной строке, находясь в любом каталоге можно одной командой создавать пустые файлы.

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

Расширение командного файла (.bat) можно не набирать и команда еще больше упрощается:

В тексте командного файла присутствует проверка, задано ли имя
создаваемого файла в командной строке (if “%1%” EQU “” goto error), и если не
задано – выводится сообщение об ошибке и командный файл завершает
свою работу.

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

Some Final Polish

I always include these commands at the top of my batch scripts:

SETLOCAL ENABLEEXTENSIONS
SET me=%~n0
SET parent=%~dp0

Заключение

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