Как принять несколько наборов параметров в пакетном файле? - PullRequest
1 голос
/ 27 января 2020

Я пытаюсь сделать мой пакетный файл более гибким.

Представьте себе пакетный файл, который может принимать несколько наборов аргументов.

Так что вместо того, чтобы делать,

myexe "path1" /s1 /s2 | myexe path2 | ...  

Можно просто сделать,

myexe ["path1" /s1 /s2] [path2] [...]

Итак, первое, что мне пришло в голову, - это переименовать myexe в _myexe__ и создать командный файл с именем myexe.bat.

Содержание myexe.bat:

@echo off

if "%1"=="" goto default

:start
_myexe__ %1
shift
if not "%1"=="" goto default
goto end

:default
_myexe__
:end

Теперь первое, что приходит в голову, - это использовать двойные кавычки,

Но здесь есть одна загвоздка, что если один из параметры используют двойные кавычки (например, "path1" в приведенном выше примере)

Я бы предпочел использовать [], чтобы он выглядел более чётко, и сделать мой пакетный файл достаточно умным, чтобы различать одиночные и множественные наборы без явного определения это.

Есть ли способ сделать это без использования %varname~:sI,eI%?

Ответы [ 3 ]

0 голосов
/ 27 января 2020

Используйте кавычки, чтобы сгруппировать ваши наборы и псевдо-кавычки для отдельных параметров. Сначала разделите на наборы, затем преобразуйте псевдоквоты и разделите каждый набор:

@echo off
setlocal enabledelayedexpansion

echo all params: %*
set n=0
for %%a in (%*) do (
  set /a n+=1
  echo param !n!: %%~a
  set "params=%%~a"
  call :disassemble !params:'="!
)
goto :eof

:disassemble
echo all subparams: %*
set m=0
for %%b in (%*) do (
  set /a m+=1
  echo subparam !n!/!m!: %%~b
)

Ввод:

test.bat "'alpha' 'beta' 'delta'" "'gamma' 'with space'"

Выход:

all params: "'alpha' 'beta' 'delta'" "'gamma' 'with space'"
param 1: 'alpha' 'beta' 'delta'
all subparams: "alpha" "beta" "delta"
subparam 1/1: alpha
subparam 1/2: beta
subparam 1/3: delta
param 2: 'gamma' 'with space'
all subparams: "gamma" "with space"
subparam 2/1: gamma
subparam 2/2: with space

Недостатки: Ваши параметры не могут содержать ! или % (все в порядке <>|&) или символы подстановки (*, ?) (спасибо, Дбенхем)

0 голосов
/ 29 января 2020

Анализировать аргументы с помощью простого FOR небезопасно, поскольку он повредит аргументы, содержащие * или ? - он будет предполагать, что вы ищете файлы, и расширит аргумент во все файлы, соответствующие маске подстановочного знака.

Я также разделяю озабоченность Compo по поводу присвоения имени вашему пакетному файлу myexe.bat, даже если вы переименовали myexe.exe в другое. Лучше назвать ваш скрипт чем-то вроде myexeMulti.bat.

Я всегда использую GOTO l oop всякий раз, когда мне нужно надежно разобрать параметры, и я не могу контролировать их содержимое.

I Рекомендуется использовать параметр + для разделения каждой группы параметров.

Ниже приведено надежное решение, которое всегда будет работать при условии:

  • Вам никогда не нужно передавать + как параметр для myexe
  • Все параметры, содержащие символы-кавычки, заключены в кавычки

Часто люди проверяют, есть ли какие-либо аргументы, с помощью if "%~1" neq "", но этот тест ложно обрабатывает "" в качестве аргумента Я веду себя консервативно и предполагаю, что вы, возможно, захотите передать "" в качестве аргумента, поэтому я проверяю с помощью set arg=%1, а затем проверяю, определен ли arg.

@echo off
setlocal
set "args="
:loop
set arg=%1
if defined arg (
  if .%1==.+ (
    myexe %args%
    set "args="
  ) else (
    set args=%args% %1
  )
  shift /1
  goto loop
)
myexe %args%
exit /b

Если пользователь выполняет

myExeMulti /s1 /s2 "*" + + "abc" /s1 + "abc" /s1 /s2

тогда скрипт выполнит

myexe  /s1 /s2 "*"
myexe
myexe  "abc" /s1
myexe  "abc" /s1 /s2
0 голосов
/ 27 января 2020

Если в команде всегда ровно три (3) параметра, это можно использовать для последовательной обработки групп. Замените echo %1 %2 %3 на программу, которую вы хотите запустить; _myexe_ %1 %2 %3. Пожалуйста, попробуйте это с вашими требованиями для групп параметров.

ECHO OFF
SET /A "EXITCODE=0"

:head
IF NOT "%1" == "" (
    echo %1 %2 %3
    SET /A "EXITCODE=%ERRORLEVEL%"
    IF %EXITCODE% NEQ 0 (GOTO TheEnd)
    SHIFT & SHIFT & SHIFT
    GOTO Head
)

:TheEnd
EXIT /B %EXITCODE%

Этот сценарий производит:

C:>CALL rotparms.bat 1 2 3 4 5 6 7 8 9 10 11 12
1 2 3
4 5 6
7 8 9
10 11 12

Символы, используемые в регулярном выражении, включают: (от https://www.regular-expressions.info/characters.html)

backslash \
caret ^
dollar sign $
period or dot .
vertical bar or pipe symbol |
question mark ?
asterisk or star *
plus sign +
opening and closing parenthesis (
opening and closing square bracket [
opening and closing curly brace {

Обновление:

Обработка наборов параметров с использованием FOR l oop может работать. Группы параметров должны быть ограничены символами QUOTATION MARK.

C:>type rotparms4.bat
@ECHO OFF
REM Invoke this by using a QUOTATION MARK character around parameter sets.
REM Eg: rotparms4.bat "1 2" "here and there" "when "we" get ready"
ECHO all = %*

FOR %%A in (%*) DO (
    ECHO parameters = %%~A
)

C:>CALL rotparms4.bat "1 2" "here and there" "when "we" get ready"
all = "1 2" "here and there" "when "we" get ready"
parameters = 1 2
parameters = here and there
parameters = when "we" get ready
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...