2009-04-17 3 views
34

В следующем примере я хочу вызвать дочерний пакетный файл из родительского пакетного файла и передать все остальные параметры дочернему.Есть ли способ указать последние n параметров в пакетном файле?

C:\> parent.cmd child1 foo bar 
C:\> parent.cmd child2 baz zoop 
C:\> parent.cmd child3 a b c d e f g h i j k l m n o p q r s t u v w x y z 

Внутри parent.cmd, мне нужно раздеться% 1 из списка параметров и передавать только оставшиеся параметры детского сценария.

set CMD=%1 
%CMD% <WHAT DO I PUT HERE> 

Я исследовал использование SHIFT с% *, но это не работает. Хотя SHIFT будет перемещать позиционные параметры вниз на 1,% * по-прежнему относится к исходным параметрам.

У кого-нибудь есть идеи? Должен ли я просто отказаться от установки Linux?

+0

Точный дубликат? http://stackoverflow.com/questions/382587/how-to-get-batch-file-parameters-from-nth-position-on –

+0

На этот вопрос ответил код, который не работал. Я добавил заявления на мой вопрос, чтобы помочь прояснить, и похоже, что я получил солидный ответ от Йоханнеса. – Dave

+0

О, кстати, при вызове партий из других партий всеми манерами используйте звонок. В противном случае вызывающий пакетный файл не будет работать дальше после вызывания вызываемой партии. (Может или не может быть здесь актуальным, просто некоторые рекомендации :-)) – Joey

ответ

62

%*, к сожалению, всегда будет распространяться на все исходные параметры. Но вы можете использовать следующий фрагмент кода, чтобы создать переменную, содержащую все, кроме первого параметра:

rem throw the first parameter away 
shift 
set params=%1 
:loop 
shift 
if [%1]==[] goto afterloop 
set params=%params% %1 
goto loop 
:afterloop 

Я думаю, что это можно сделать короче, хотя ... Я не пишу эти рода вещи очень часто :)

Должно работать.

+0

Как сказал Tbee, это не сработает, если в ваших остальных аргументах есть '='. Кажется, единственный реальный способ решить это - написать программу для правильного извлечения ваших аргументов - оболочка cmd слишком неаккуратная. –

+3

Этот подход терпит неудачу, если у вас есть назначения в параметрах, например. «А = Ь». Затем вы получите два отдельных параметра «a» и «b», потеряв =. – Tbee

+2

В этом случае укажите аргумент. 'cmd' считает еще несколько символов разделителями аргументов, например'; 'или', '. – Joey

14

Вот одна линия подход А с использованием «для» команды ...

for /f "usebackq tokens=1*" %%i in (`echo %*`) DO @ set params=%%j 

Эта команда присваивает 1-й параметр на «я», а остальное (обозначается «*») присваиваются " j ", который затем используется для установки переменной params.

+0

Это не удается, когда первый аргумент содержит пробел (например, «первый аргумент» второй третей »устанавливает параметры в« аргумент »второй трети' – EM0

5

Вы можете на самом деле просто сделать это:

%* 

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

1

Другой способ (почти такой же, как Alxander Птичье) без выполнения ЭХО в субоболочке:

FOR /F "usebackq tokens=1*" %%I IN ('%*') DO SET params=%%J 

так, линия

%CMD% <WHAT DO I PUT HERE> 

будет выглядеть следующим образом:

FOR /F "usebackq tokens=1*" %%I IN ('%*') DO %CMD% %%J 

проблема заключается в том, что если параметры включают цитируемые stings с пробелами внутри, cmd.exe будет анализировать их соответствующим образом для использования (% 1), но FOR будет игнорировать кавычки. В этом конкретном случае это вредит, если первый параметр содержит пробел или больше, что вполне возможно, учитывая, что% CMD% может быть, например, «C: \ Program Files \ Internet Explorer \ iexplore.exe».

Итак, вот еще один ответ.

7

линия

%CMD% <WHAT DO I PUT HERE> 

должен быть изменен на:

(
SETLOCAL ENABLEDELAYEDEXPANSION 
SET Skip=1 

FOR %%I IN (%*) DO IF !Skip! LEQ 0 ( 
     SET params=!params! %%I 
    ) ELSE SET /A Skip-=1 
) 
(
ENDLOCAL 
SET params=%params% 
) 
%CMD% %params% 

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

0

Хотя на самом деле «за» решение превосходит во многих случаях, для чего-то простого я часто просто сохранить и перенести другие аргументы в сторону, а затем использовать %* как обычно (практически та же стратегия, часто работает $* или [email protected] в {,ba,da,k,*}sh):

пример:

:: run_and_time_me.cmd - run a command with the arguments passed, while also piping 
::      the output through a second passed-in executable 

@echo off 

set run_me=%1 
set pipe_to_me=%2 
shift 
shift 

:: or 
:: set run_me=%1 
:: shift 
:: set pipe_to_me=%1 
:: shift 

%run_me% %* | %pipe_to_me% 

во всяком случае, я видел этот вопрос давно ответил, но полагал, что я Др op в моих двух центах, поскольку это было то, чего я не видел, и потому, что это был тот ответ, который мне нужен, когда я, наконец, через несколько лет вернулся через него ... и пошел «о ... дух». :)

+1

сдвиг не влияет на% * так что это передает * все * исходные аргументы% run_me%, включая% 1 и% 2. В принятом ответе говорится, что «% * всегда будет распространяться на все исходные параметры, к сожалению». – Naaff

0

Я столкнулся с этим вопросом, пока сталкивался с подобной проблемой, но решил это с помощью другого подхода. Вместо повторного создания строки ввода с использованием цикла (как в ответе @Joey) я просто удалил первый параметр из входной строки.

set _input=%* 
set params=!_input:%1 =! 
call OTHER_BATCH_FILE.cmd %params% 

Конечно, это предполагает, что все параметры различны.

 Смежные вопросы

  • Нет связанных вопросов^_^