Пакетные файлы - количество аргументов командной строки

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

например. если у вас есть:

myapp foo bar

В оболочке:

  • $# → 2
  • $* → foo bar
  • $0 → myapp
  • $1 → foo
  • $2 → bar

В пакетном режиме

  • ?? → 2 < ---- какая команда?!
  • % * → foo bar
  • % 0 → myapp
  • % 1 → foo
  • % 2 → bar

Итак, я огляделся, и либо я смотрю не в том месте, либо я слепой, но я не могу найти способ получить количество аргументов командной строки, переданных в.

Есть ли команда, похожая на shell "$ #" для пакетных файлов?

пс. ближайший, который я нашел, - это перебирать% 1 и использовать "shift", но мне нужно отсылать% 1,% 2 и т.д. позже в script, чтобы не было хорошего.

Ответ 1

Поведение в битке приводит к следующему результату: wikibooks:

set argC=0
for %%x in (%*) do Set /A argC+=1

echo %argC%

Кажется, что cmd.exe немного изменился со старых дней DOS:)

Ответ 2

Вы склонны обрабатывать количество аргументов с такой логикой:

IF "%1"=="" GOTO HAVE_0
IF "%2"=="" GOTO HAVE_1
IF "%3"=="" GOTO HAVE_2

и др.

Если у вас более 9 аргументов, тогда вы используете этот подход. Существуют различные хаки для создания счетчиков, которые вы можете найти здесь здесь, но будьте осторожны, это не для слабонервных.

Ответ 3

Функция :getargc ниже может быть тем, что вы ищете.

@echo off
setlocal enableextensions enabledelayedexpansion
call :getargc argc %*
echo Count is %argc%
echo Args are %*
endlocal
goto :eof

:getargc
    set getargc_v0=%1
    set /a "%getargc_v0% = 0"
:getargc_l0
    if not x%2x==xx (
        shift
        set /a "%getargc_v0% = %getargc_v0% + 1"
        goto :getargc_l0
    )
    set getargc_v0=
    goto :eof

Он в основном повторяет один раз над списком (который является локальным для функции, поэтому сдвиги не будут влиять на список в основной программе), считая их до тех пор, пока не закончится.

Он также использует отличный трюк, передавая имя возвращаемой переменной, которая должна быть задана функцией.

Основная программа просто иллюстрирует, как ее вызывать и повторять аргументы после этого, чтобы убедиться, что они не тронуты:

C:\Here> xx.cmd 1 2 3 4 5
    Count is 5
    Args are 1 2 3 4 5
C:\Here> xx.cmd 1 2 3 4 5 6 7 8 9 10 11
    Count is 11
    Args are 1 2 3 4 5 6 7 8 9 10 11
C:\Here> xx.cmd 1
    Count is 1
    Args are 1
C:\Here> xx.cmd
    Count is 0
    Args are
C:\Here> xx.cmd 1 2 "3 4 5"
    Count is 3
    Args are 1 2 "3 4 5"

Ответ 4

Попробуйте следующее:

SET /A ARGS_COUNT=0    
FOR %%A in (%*) DO SET /A ARGS_COUNT+=1    
ECHO %ARGS_COUNT%

Ответ 5

Если количество аргументов должно быть точным числом (меньше или равно 9), то это простой способ проверить его:

if "%2" == "" goto args_count_wrong
if "%3" == "" goto args_count_ok

:args_count_wrong
echo I need exactly two command line arguments
exit /b 1

:args_count_ok

Ответ 6

Избегает использования цикла shift или for за счет размера и удобочитаемости.

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set /a arg_idx=1
set "curr_arg_value="
:loop1
if !arg_idx! GTR 9 goto :done
set curr_arg_label=%%!arg_idx!
call :get_value curr_arg_value !curr_arg_label!
if defined curr_arg_value (
  echo/!curr_arg_label!: !curr_arg_value!
  set /a arg_idx+=1
  goto :loop1
)
:done
set /a cnt=!arg_idx!-1
echo/argument count: !cnt!
endlocal
goto :eof

:get_value
(
  set %1=%2
)

Вывод:

count_cmdline_args.bat testing more_testing arg3 another_arg

%1: testing
%2: more_testing
%3: arg3
%4: another_arg
argument count: 4

EDIT: Используемый здесь "трюк" включает в себя:

  • Построение строки, представляющей переменную аргумента командной строки в данный момент (например, "% 1", "% 2" и т.д.), используя строку, содержащую символ процента (%%) и переменную счетчика arg_idx на каждой итерации цикла.

  • Сохранение этой строки в переменной curr_arg_label.

  • Передача как этой строки (!curr_arg_label!), так и имени возвращаемой переменной (curr_arg_value) в примитивную подпрограмму get_value.

  • В подпрограмме первое значение аргумента (%1) используется в левой части назначения (set) и его втором аргументе (%2) справа. Однако, когда передается второй аргумент подпрограммы, он разрешается в значение аргумента командной строки основной программы с помощью интерпретатора команд. То есть, то, что передано, не является, например, "% 4", но независимо от значения, которое имеет четвертая переменная аргумента командной строки ( "another_arg" в использовании примера).

  • Затем переменная, заданная подпрограмме как возвращаемая переменная (curr_arg_value), проверяется на undefined, что произойдет, если отсутствующий аргумент командной строки отсутствует. Первоначально это было сравнение значения возвращаемой переменной, заключенного в квадратные скобки, в пустые квадратные скобки (что является единственным способом, который я знаю о тестировании программ или аргументов подпрограммы, которые могут содержать кавычки, и было упущено оставшееся от фазы проб и ошибок), но с тех пор фиксируется так, как сейчас.