Тема: CMD/BAT: BusyBox запускалка, BusyBox Runner
Доработал обертку-запускалку для BusyBox, компактного набора консольных утилит Юникс.
Требования
Для работы необходимо:
-- Загрузить скрипт bb.bat из репозитория https://github.com/ildar-shaimordanov/m … md/busybox.
-- Загрузить сам BusyBox со страницы https://frippery.org/busybox/ (любая, 64- или 32-битная, по вашему желанию).
-- Поместить оба файла в каталог, видимый из переменной окружения $PATH.
или...
-- Загрузить скрипт bb.bat из репозитория https://github.com/ildar-shaimordanov/m … md/busybox.
-- Поместить файл в каталог, видимый из переменной окружения $PATH.
-- Чтобы загрузить последнюю версию 32-битной или 64-битной сборки BusyBox, выполнить одну из команд, соответственно:
bb --download win32
или
bb --download win64
Загруженный файл сохранется в одном каталоге со скриптом. Для загрузки требуется PowerShell.
Применение
1. Запуск встроенных функций BusyBox
Запустить функцию и передать, если необходимо, опции:
bb function [function-options]
Фактически, это тоже самое, что делает BusyBox:
busybox function [function-options]
2. Запуск команды или скрипта из переменной $PATH
Выполнить внешнюю команду или скрипт, найденные в переменной $PATH или казанные по абсолютному или относительному пути:
bb [shell-options] [DIR]command [command-options]
busybox [sh [shell-options]] [DIR]command [command-options]
3. Запуск однострочного скрипта
bb [shell-options] -c "script"
busybox sh [shell-options] -c "script"
Исходный код
Актуальные на момент написания этого текста версии скриптов.
bb.bat
: ; [ $# -gt 0 ] || exec sed -n "s/^:: \?//p" << '::::'
:: Simplify running scripts and commands with BusyBox
::
:: USAGE
:: Print BusyBox help pages
:: bb --help
:: bb --version
:: bb --list[-full]
::
:: Run a built-in BusyBox function
:: bb function [function-options]
::
:: Run an executable from $PATH or specified with DIR
:: bb [shell-options] [DIR]command [command-options]
::
:: Run a one-liner script
:: bb [shell-options] -c "script"
::
:: Download the latest 32-bit or 64-bit build of BusyBox
:: bb --download win32
:: bb --download win64
::
:: SEE ALSO
:: Learn more about BusyBox following these links:
::
:: https://busybox.net/
:: https://frippery.org/busybox/
:: https://github.com/rmyorston/busybox-w32
::::
: << '____CMD____'
@echo off
setlocal
set "BB_EXE="
:: First: 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"
:: Second: 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"
:: Fail, if BusyBox not found and download not required
if not defined BB_EXE if /i not "%~1" == "--download" (
2>nul echo:ERROR: BusyBox executable not found
exit /b 1
)
:: ========================================================================
:: Try to download
if /i "%~1" == "--download" (
for %%p in ( "powershell.exe" ) do if "%%~$PATH:p" == "" (
>&2 echo:%%p is required
goto :EOF
)
set "BB_URL="
set "BB_DST="
if /i "%~2" == "win32" (
set "BB_URL=https://frippery.org/files/busybox/busybox.exe"
set "BB_DST=%~dp0busybox.exe"
) else if /i "%~2" == "win64" (
set "BB_URL=https://frippery.org/files/busybox/busybox64.exe"
set "BB_DST=%~dp0busybox64.exe"
) else (
>&2 echo:win32 or win64 required
goto :EOF
)
echo:Downloading started...
set BB_URL
set BB_DST
powershell -NoLogo -NoProfile -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;$w=New-Object System.Net.WebClient;$w.DownloadFile($Env:BB_URL,$Env:BB_DST)"
echo:Downloading completed
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"
:: ========================================================================
if defined BB_DEBUG (
@prompt +$S
@echo on
)
"%BB_EXE%" sh "%~f0" %*
exit /b %ERRORLEVEL%
:: ========================================================================
____CMD____
case "$1" in
'' )
# It's never reachable part - learn why at the top of the script
exit
;;
--help | --list | --list-full )
busybox $1
exit
;;
--version )
busybox --help | head -2
exit
;;
esac
# Add the BusyBox location to the $PATH
[[ ";$PATH;" =~ ";$( dirname "$0" );" ]] \
|| PATH="$( dirname "$0" );$PATH"
[ -z "$BB_DEBUG" ] || set -x
case "$1" in
-* | +* )
sh "$@"
;;
* )
eval 'exec "$@"'
;;
esac
# =========================================================================
# EOF
clp
Скрипт для работы с буфером обмена в обе стороны (копировать в буфер, копировать из буфера)
https://github.com/ildar-shaimordanov/m … /clipboard
#!/bin/sh
# =========================================================================
CLIP_GET=''
CLIP_PUT=''
CLIP_DEV=''
CLIP_IMP=''
CLIP_EOL=''
DOS2UNIX=''
UNIX2DOS=''
CLIP_ENC=''
ICONV=''
VERBOSELY=''
# =========================================================================
print_usage() {
echo "\
Copy data from and/or to the clipboard
Usage:
clp [OPTIONS]
clp [OPTIONS] | ...
... | clp [OPTIONS]
Formatting options
-u dos2unix
-d unix2dos
Encoding options
-f encoding
-t encoding
Encodings for input and output, respectively
-c Discard silently unconvertible characters
Information options
-h Display this help message
-v Display the executable command
-V Display versions of tools
"
}
# shellcheck disable=SC3028
print_version() {
exec 2>/dev/null
uname -s || cmd /c ver || echo "${OSTYPE:-${OS:-unknown}}"
printf 'imp=%s eol=%s enc=%s\n' \
"${CLIP_DEV:-${CLIP_IMP:-${CLIP_GET%% *},${CLIP_PUT%% *}}}" \
"${DOS2UNIX%% *},${UNIX2DOS%% *}" \
"${ICONV%% *}"
}
# =========================================================================
die() {
warn "$*"
exit 1
}
warn() {
echo "$*">&2
}
not_supported() {
warn "$1 not supported"
}
# =========================================================================
# shellcheck disable=SC2016
getclip() {
posh \
'Get-Clipboard -Raw | Write-Host -NoNewLine'
}
# shellcheck disable=SC2016
putclip() {
posh \
'$b = @(); $i = [Console]::OpenStandardInput();' \
'do { $b += @{ c = 0; d = [byte[]]::new(1048576) } }' \
'while ( $b[-1].c = $i.Read($b[-1].d, 0, $b[-1].d.count) )' \
'$a = $b | ForEach-Object { $_.d[0..($_.c - 1)] };' \
'[System.Text.Encoding]::UTF8.GetString($a) | Set-Clipboard'
}
posh() {
powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "$*"
}
# =========================================================================
# shellcheck disable=SC3028
case "$OSTYPE" in
darwin* ) CLIP_OS=darwin ;;
* ) CLIP_OS='' ;;
esac
if command -v xsel >/dev/null
then
# Unixes: first attempt - preferable way
CLIP_GET='xsel --clipboard --output'
CLIP_PUT='xsel --clipboard --input'
elif command -v xclip >/dev/null
then
# Unixes: second attempt - another way
CLIP_GET='xclip -selection clipboard -out'
CLIP_PUT='xclip -selection clipboard -in'
elif [ "$CLIP_OS" = "darwin" ]
then
# OSX? It has its own way
command -v pbpaste >/dev/null && CLIP_GET='pbpaste'
command -v pbcopy >/dev/null && CLIP_PUT='pbcopy'
elif [ -c /dev/clipboard ]
then
# Cygwin?
CLIP_DEV='/dev/clipboard'
CLIP_GET="cat - < $CLIP_DEV"
CLIP_PUT="cat - > $CLIP_DEV"
elif [ "$OS" = "Windows_NT" ] && command -v powershell >/dev/null
then
# BusyBox, UnxUtils or something else similar?
CLIP_IMP='powershell'
CLIP_GET='getclip'
CLIP_PUT='putclip'
fi
# =========================================================================
if command -v dos2unix >/dev/null
then
DOS2UNIX=dos2unix
elif command -v sed >/dev/null
then
DOS2UNIX='sed "s/\r$//"'
elif command -v awk >/dev/null
then
DOS2UNIX='awk -v RS="\r?\n" -v ORS="\n" 1'
elif command -v gawk >/dev/null
then
DOS2UNIX='gawk -v RS="\r?\n" -v ORS="\n" 1'
fi
if command -v unix2dos >/dev/null
then
UNIX2DOS=unix2dos
elif command -v sed >/dev/null
then
UNIX2DOS='sed "s/[^\r]$/&\r/"'
elif command -v awk >/dev/null
then
UNIX2DOS='awk -v RS="\r?\n" -v ORS="\r\n" 1'
elif command -v gawk >/dev/null
then
UNIX2DOS='gawk -v RS="\r?\n" -v ORS="\r\n" 1'
fi
# =========================================================================
if command -v iconv >/dev/null
then
ICONV='iconv'
fi
# =========================================================================
while getopts ":hVvudf:t:c" arg
do
case "$arg" in
h ) print_usage ; exit ;;
V ) print_version ; exit ;;
v ) VERBOSELY=1 ;;
u ) CLIP_EOL="$DOS2UNIX" ; [ -n "$CLIP_EOL" ] || not_supported dos2unix ;;
d ) CLIP_EOL="$UNIX2DOS" ; [ -n "$CLIP_EOL" ] || not_supported unix2dos ;;
f | t | c )
CLIP_ENC="$ICONV"
CLIP_ENC_OPTS="$CLIP_ENC_OPTS -$arg$OPTARG"
[ -n "$CLIP_ENC" ] || not_supported iconv
;;
: ) die "Argument expected for -$OPTARG" ;;
* ) die "Illegal option: -$OPTARG" ;;
esac
done
if [ -t 0 ]
then
# clp
# clp | ...
[ -n "$CLIP_GET" ] || die "No tool to paste from clipboard"
CLIP_RUN="$CLIP_GET"
CLIP_RUN="$CLIP_RUN${CLIP_EOL:+ | $CLIP_EOL}"
CLIP_RUN="$CLIP_RUN${CLIP_ENC:+ | $CLIP_ENC$CLIP_ENC_OPTS}"
elif [ -t 1 ]
then
# ... | clp
[ -n "$CLIP_PUT" ] || die "No tool to copy to clipboard"
CLIP_RUN="$CLIP_PUT"
CLIP_RUN="${CLIP_EOL:+$CLIP_EOL | }$CLIP_RUN"
CLIP_RUN="${CLIP_ENC:+$CLIP_ENC$CLIP_ENC_OPTS | }$CLIP_RUN"
fi
# ... | clp | ...
[ -n "$CLIP_RUN" ] || die "Useless use in the middle of the pipe"
[ -n "$VERBOSELY" ] && set -x
eval "$CLIP_RUN"
# =========================================================================
# EOF