1 (изменено: Rumata, 2020-11-17 03:19:39)

Тема: CMD/BAT: BusyBox запускалка, BusyBox Runner


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

Доработал обертку-запускалку для BusyBox, компактного набора консольных утилит Юникс.

Для работы необходимо:

-- Загрузить сам BusyBox со страницы https://frippery.org/busybox/ (любая, 64- или 32-битная, по вашему желанию).
-- Загрузить скрипт bb.bat из репозитория https://github.com/ildar-shaimordanov/busybox-runner.
-- Поместить оба файла в каталог, видимый из переменной окружения $PATH.

Применение

1. Запуск встроенных функций BusyBox

Запустить функцию и передать, если необходимо, опции:

bb function [function-options]

Фактически, это тоже самое, что делает BusyBox:

busybox function [function-options]

2. Запуск внешних команд и скриптов из встроенной облочки BusyBox

BusyBox не умеет распознавать внешние команды, даже если они находятся в $PATH. Втстроенная оболочка BusyBox's умеет. Следующие примеры идентичные:

bb [shell-options] -c "command [command-options]"
busybox sh [shell-options] -c "command [command-options]"

3. Запуск команды или скрипта из переменной $PATH

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

bb command [command-options]
busybox sh -c "command [command-options]"

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

Что надо/хотелось бы доделать

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

Актуальная на момент написания этого текста версия скрипта:


0</* :
:: Simplify running BusyBox
::
:: USAGE
::   Print BusyBox help page
::     bb --help
::
::   Run a built-in BusyBox function
::     bb function [function-options]
::
::   Run an external command or script from within shell
::     bb [shell-options] -c "command [command-options]"
::
::   Run a command or script found in $PATH
::     bb command [command-options]
::
:: SEE ALSO
::   Learn more about BusyBox following these links:
::
::   https://busybox.net/
::   https://frippery.org/busybox/
::   https://github.com/rmyorston/busybox-w32
@echo off

if /i "%~1" == "" (
	"%~f0" sed -n "1 { /^::/!d; } /^::/!q; s/^:: \?//p" "%~f0"
	if errorlevel 1 cscript //nologo //e:javascript "%~f0" < "%~f0"
	goto :EOF
)

:: ========================================================================

setlocal

set "BB_EXE="

:: Look for the instance in $PATH
for %%f in (
	busybox.exe
	busybox64.exe
) do if not "%%~$PATH:f" == "" set "BB_EXE=%%~$PATH:f"

:: Look for the latest instance next to this script
if not defined BB_EXE for /f "tokens=*" %%f in ( '
	dir /b /o-n "%~dp0busybox*.exe" 2^>nul
' ) do if exist "%%~f" set "BB_EXE=%~dp0%%~f"

if not defined BB_EXE (
	2>nul echo:ERROR: BusyBox executable not found
	exit /b 1
)

:: ========================================================================

if /i "%~1" == "--help" (
	"%BB_EXE%" --help
	goto :EOF
)

:: ========================================================================

:: Locate the history file in the $TEMP directory
set "HISTFILE=%TEMP%\.ash_history"

:: Locate the history file next to Busybox executable
::set "HISTFILE=%~dp0.ash_history"

:: Another way to locate the history file is to set HOME dir
::for %%p in ( "%~dp0." ) do set "HOME=%%~fp"

:: ========================================================================

for /f "tokens=* delims=-" %%n in ( "%~1" ) do if not "%%~$PATH:n" == "" (
	"%BB_EXE%" sh -c "%*"
) else if "%~1" == "%%~n" (
	"%BB_EXE%" %*
) else (
	"%BB_EXE%" sh %*
)

goto :EOF

:: ========================================================================

:: EOF

*/0;

WScript.StdOut.Write(
WScript.StdIn.ReadAll()
	.replace(/^(?!::).+$/m, '')		// remove the first line
	.replace(/\n(?!::)[\s\S]+/, '\n')	// remove the rest if the file
	.replace(/^::[ ]?/gm, '')		// remove all leading "::"
);

// ========================================================================

// EOF
( 2 * b ) || ! ( 2 * b )

2 (изменено: Rumata, 2020-11-17 14:36:53)

Re: CMD/BAT: BusyBox запускалка, BusyBox Runner

Немного "косметических" изменений:
-- чуть расширил страницу справки скрипта
-- расширил обработку основных опций BusyBox: --help, --list, --list-full
-- удалил javascript код
-- полная справка выводится только средствами самого BusyBox и только при его наличии
-- улучшил поиск самого BusyBox


:: Simplify running BusyBox
::
:: USAGE
::   Print BusyBox help pages
::     bb --help
::     bb --list[-full]
::
::   Run a built-in BusyBox function
::     bb function [function-options]
::
::   Run an external command or script from within shell
::     bb [shell-options] -c "command [command-options]"
::
::   Run a command or script found in $PATH
::     bb command [command-options]
::
:: SEE ALSO
::   Learn more about BusyBox following these links:
::
::   https://busybox.net/
::   https://frippery.org/busybox/
::   https://github.com/rmyorston/busybox-w32
@echo off

setlocal

set "BB_EXE="

:: Look for the instance in $PATH
for %%f in (
	busybox.exe
	busybox64.exe
) do if not defined BB_EXE if not "%%~$PATH:f" == "" set "BB_EXE=%%~$PATH:f"

:: Look for the latest instance next to this script
if not defined BB_EXE for /f "tokens=*" %%f in ( '
	dir /b /o-n "%~dp0busybox*.exe" 2^>nul
' ) do if not defined BB_EXE if exist "%~dp0%%~f" set "BB_EXE=%~dp0%%~f"

if not defined BB_EXE (
	2>nul echo:ERROR: BusyBox executable not found
	exit /b 1
)

:: ========================================================================

if /i "%~1" == "" (
	"%BB_EXE%" sed -n "1 { /^::/!d; } /^::/!q; s/^:: \?//p" "%~f0"
	goto :EOF
)

for %%o in (
	--help
	--list
	--list-full
) do if "%~1" == "%%~o" (
	"%BB_EXE%" %%~o
	goto :EOF
)

:: ========================================================================

:: Locate the history file in the $TEMP directory
set "HISTFILE=%TEMP%\.ash_history"

:: Locate the history file next to Busybox executable
::set "HISTFILE=%~dp0.ash_history"

:: Another way to locate the history file is to set HOME dir
::for %%p in ( "%~dp0." ) do set "HOME=%%~fp"

:: ========================================================================

for /f "tokens=* delims=-" %%n in ( "%~1" ) do if not "%%~$PATH:n" == "" (
	"%BB_EXE%" sh -c "%*"
) else if "%~1" == "%%~n" (
	"%BB_EXE%" %*
) else (
	"%BB_EXE%" sh %*
)

goto :EOF

:: ========================================================================

:: EOF
( 2 * b ) || ! ( 2 * b )