Вопрос или проблема
У меня есть очень простой bat-скрипт, и я пытаюсь выполнить его напрямую с помощью curl на машине с Windows 10.
@echo off
SETLOCAL ENABLEEXTENSIONS
SET ME=%~n0
SET PARENT=%~dp0
set VER=0.1
@echo %DATE% %TIME% - ME %ME% - PARENT %PARENT% - VER %VER%
Когда я пытаюсь выполнить его так:
curl https://example.com/test.bat | cmd
Переменные ME и PARENT не оцениваются корректно
15/10/2024 14:10:48,54 - ME %~n0 - PARENT %~dp0 - VER 0.1
Но если я загружу bat-файл и выполню его позже, он показывает значения должным образом.
15/10/2024 14:11:38,93 - ME test - PARENT C:\Users\sim\Desktop\test\ - VER 0.1
Я что-то упускаю?
Просто попробуйте:
@echo off && setlocal enableextensions
set "_ver=0.1"
set "_me=%~n0"
set "_parent=%~dp0"
call echo/%%date%% %%time%% - me %%_me%% - parent %%_parent%% - ver %%_ver%%
endlocal
curl "https://example.com/test.bat" 2>&1 | "ComSpec%" /d /e /v /c
:: или ..
curl --silent "https://example.com/test.bat" 2>&1 | "ComSpec%" /d /e /v /c
Я думал, что это связано с оценкой переменных, но, как заметил @Bodo, это просто то, что cmd не выполняет ни одного файла, а только принимает символы.
Для решения возникшей у меня ситуации я буду использовать загрузочный скрипт, который вызовет настоящий.
Спасибо за вашу помощь.
Ответ или решение
Поведение BAT-скрипта при выполнении через конвейер curl: Подробный анализ
Использование BAT-скриптов на Windows может иногда приводить к неожиданным результатам в зависимости от способа их выполнения. В данном случае, проблема связана с выполнением простого BAT-скрипта через команду curl
, которая передает содержимое скрипта в cmd
. При этом переменные %~n0
и %~dp0
, отвечающие за имя исполняемого файла и путь к его расположению, не работают так, как ожидается.
Что происходит с переменными?
При запуске BAT-скрипта напрямую (например, после загрузки файла) переменные %~n0
и %~dp0
правильно интерпретируются, так как они ссылаются на сам файл скрипта. В этом контексте:
%~n0
возвращает имя файла без расширения.%~dp0
возвращает путь к директории, где находится файл.
Однако, когда вы выполняете BAT-скрипт через команду curl
:
curl https://example.com/test.bat | cmd
cmd
не знает, что исполняется именно BAT-файл, так как получает поток данных (команды), а не ссылку на файл. Следовательно, %~n0
и %~dp0
возвращают не определенные значения, что и приводит к тому, что результат отображается как:
%~n0 -> %~n0
%~dp0 -> %~dp0
Как исправить ситуацию?
-
Выполнение через файл: Оптимальным решением будет сначала загрузить файл, а затем выполнить его:
curl -O https://example.com/test.bat cmd /c test.bat
-
Использование обертки: Вы можете создать "обертку" (bootstrap script), которая будет загружать и вызывать ваш BAT-скрипт. Например:
@echo off curl -O https://example.com/test.bat call test.bat
-
Прямое выполнение в cmd через более сложный командный вызов:
Для лучшей обработки можно использовать
COMSPEC
, чтобы гарантировать, что команды выполняются в контексте интерпретатора командной строки:curl https://example.com/test.bat | "%ComSpec%" /d /e /v /c
Эта команда заставит cmd
понимать, что он должен интерпретировать входящий поток как команды.
Заключение
Ваша проблема заключается в особенностях работы командной строки Windows и ее интерпретации переменных в контексте запуска сценариев из потоков. Чтобы избежать подобных недоразумений, рекомендуется загружать скрипты в файлы перед их выполнением или использовать специальные техники, как "обертки", чтобы корректно обрабатывать контекст выполнения. Это обеспечит более предсказуемое и надежное выполнение ваших сценариев.
Оптимизация производительности и корректная работа сценариев в Windows — важные аспекты для IT-экспертов и системных администраторов. Убедитесь, что вы всегда проверяете метод выполнения скриптов и его взаимосвязь с контекстом, в котором они запускаются.