скрипт bat ведет себя по-разному, когда он поступает из канала curl

Вопрос или проблема

У меня есть очень простой 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

Как исправить ситуацию?

  1. Выполнение через файл: Оптимальным решением будет сначала загрузить файл, а затем выполнить его:

    curl -O https://example.com/test.bat
    cmd /c test.bat
  2. Использование обертки: Вы можете создать "обертку" (bootstrap script), которая будет загружать и вызывать ваш BAT-скрипт. Например:

    @echo off
    curl -O https://example.com/test.bat
    call test.bat
  3. Прямое выполнение в cmd через более сложный командный вызов:

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

    curl https://example.com/test.bat | "%ComSpec%" /d /e /v /c

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

Заключение

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

Оптимизация производительности и корректная работа сценариев в Windows — важные аспекты для IT-экспертов и системных администраторов. Убедитесь, что вы всегда проверяете метод выполнения скриптов и его взаимосвязь с контекстом, в котором они запускаются.

Оцените материал
Добавить комментарий

Капча загружается...