Как получить даже самые странные параметры командной строки?
как обсуждалось в другом потоке Как избежать cmd.exe, интерпретируя специальные символы оболочки, такие как < > ^
получить все параметры из командной строки непросто.
Простой
set var=%1
set "var=%~1"
недостаточно, если у вас есть запрос типа
myBatch.bat abc"&"^&def
У меня есть одно решение, но ему нужен временный файл, и он также не является доказательством пули.
@echo off
setlocal DisableDelayedExpansion
set "prompt=X"
(
@echo on
for %%a in (4) do (
rem #%1#
)
) > XY.txt
@echo off
for /F "delims=" %%a in (xy.txt) DO (
set "param=%%a"
)
setlocal EnableDelayedExpansion
set param=!param:~7,-4!
echo param='!param!'
Сбой с чем-то вроде myBatch.bat% a, он отображает 4 не % a
в этой ситуации будет работать простое эхо% 1.
Это, очевидно, for-loop, но я не знаю, как это изменить.
Возможно, существует еще одно простое решение.
Мне не нужно это, чтобы решить настоящую проблему, но мне нравятся решения, которые являются пуленепробиваемыми в каждой ситуации не только в большинстве случаев.
Ответы
Ответ 1
Я не думаю, что кто-то нашел в нем какие-либо дыры, за исключением невозможности читать строки новой строки в параметрах:
@echo off
setlocal enableDelayedExpansion
set argCnt=1
:getArgs
>"%temp%\getArg.txt" <"%temp%\getArg.txt" (
setlocal disableExtensions
set prompt=#
echo on
for %%a in (%%a) do rem . %1.
echo off
endlocal
set /p "arg%argCnt%="
set /p "arg%argCnt%="
set "arg%argCnt%=!arg%argCnt%:~7,-2!"
if defined arg%argCnt% (
set /a argCnt+=1
shift /1
goto :getArgs
) else set /a argCnt-=1
)
del "%temp%\getArg.txt"
set arg
Выше приведено оживленное обсуждение DosTips - http://www.dostips.com/forum/viewtopic.php?p=13002#p13002. Пользователь DosTips Liviu придумал критический фрагмент SETLOCAL DisableExtensions
.
Ответ 2
Нижеприведенный код основан на бессвязном Foolproof Counting of Arguments на DosTips и этот ответ jeb:
@echo off & setLocal enableExtensions disableDelayedExpansion
(call;) %= sets errorLevel to 0 =%
:: initialise variables
set "paramC=0" & set "pFile=%tmp%\param.tmp"
:loop - the main loop
:: inc param counter and reset var storing nth param
set /a paramC+=1 & set "pN="
:: ECHO is turned on, %1 is expanded inside REM, GOTO jumps over REM,
:: and the output is redirected to param file
for %%A in (%%A) do (
setLocal disableExtensions
set [email protected]
echo on
for %%B in (%%B) do (
@goto skip
rem # %1 #
) %= for B =%
:skip - do not re-use this label
@echo off
endLocal
) >"%pFile%" %= for A =%
:: count lines in param file
for /f %%A in ('
find /c /v "" ^<"%pFile%"
') do if %%A neq 5 (
>&2 echo(multiline parameter values not supported & goto die
) %= if =%
:: extract and trim param value
for /f "useBack skip=3 delims=" %%A in ("%pFile%") do (
if not defined pN set "pN=%%A"
) %= for /f =%
set "pN=%pN:~7,-3%"
:: die if param value is " or "", else trim leading/trailing quotes
if defined pN (
setLocal enableDelayedExpansion
(call) %= OR emulation =%
if !pN!==^" (call;)
if !pN!=="" (call;)
if errorLevel 1 (
for /f delims^=^ eol^= %%A in ("!pN!") do (
endLocal & set "pN=%%~A"
) %= for /f =%
) else (
>&2 echo(empty parameter values (""^) not supported & goto die
) %= if errorLevel =%
) else (
:: no more params on cmd line
set /a paramC-=1 & goto last
) %= if defined =%
:: die if param value contains "
if not "%pN:"=""%"=="%pN:"=%" (
>&2 echo(quotes (^"^) in parameter values not supported & goto die
) %= if =%
:: assign nth param, shift params, and return to start of loop
set "param%paramC%=%pN%" & shift /1 & goto loop
:last - reached end of params
:: no param values on cmd line
if %paramC% equ 0 (
>&2 echo(no parameter values found & goto die
) %= if =%
:: list params
set param
goto end
:die
(call) %= sets errorLevel to 1 =%
:end
:: exit with appropriate errorLevel
endLocal & goto :EOF
Следующие условия немедленно прекратят выполнение программы:
- не найдены параметры
- многострочный параметр
- для последнего параметра разрешен пустой параметр (
"""
или "
)
- один или несколько кавычек (
"
) в значении параметра
Чтобы облегчить эти ограничения, просто закомментируйте соответствующие строки. Прочтите встроенные комментарии для получения дополнительной информации. Не пытайтесь отключить многолинейную ловушку параметров!
Ответ 3
Это зависит от пользователя, который вводит команду для удаления каких-либо специальных символов. Ваша программа не может ничего сделать о том, что делает оболочка до запуска вашей программы. Нет другого "пуленепробиваемого" решения.