2009-04-17 11 views
34

निम्नलिखित उदाहरण में, मैं अभिभावक बैच फ़ाइल से एक बच्चे बैच फ़ाइल को कॉल करना चाहता हूं और सभी शेष पैरामीटर को बच्चे को पास करना चाहता हूं।क्या बैच फ़ाइल में अंतिम एन पैरामीटर इंगित करने का कोई तरीका है?

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 से नीचे ले जाएगा,% * अभी भी मूल मानकों को संदर्भित करता है।

किसी के पास कोई विचार है? क्या मुझे बस लिनक्स छोड़ना और इंस्टॉल करना चाहिए?

+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

जैसा कि टीबी ने कहा था, यदि आपके शेष तर्कों में '=' है तो यह काम नहीं करता है। ऐसा लगता है कि इसे हल करने का एकमात्र असली तरीका है कि आप अपने तर्कों को सही तरीके से निकालने के लिए एक प्रोग्राम लिखना चाहते हैं - cmd shell बहुत ही गड़बड़ है। –

+3

यदि आपके पास पैरामीटर में असाइनमेंट हैं, तो यह दृष्टिकोण विफल हो जाता है, उदा। "A = b"। फिर आपको दो अलग-अलग पैरामीटर "ए" और "बी" मिलेंगे, जो = को खो देंगे। – Tbee

+2

उस मामले में, तर्क उद्धृत करें। 'cmd' कुछ और वर्णों को तर्क विभाजक होने के लिए भी मानता है, जैसे'; 'या', '। – Joey

14

यहाँ का उपयोग कर आदेश "के लिए" ...

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

यह आदेश 1 पैरामीटर प्रदान करती है "मैं" और आराम करने के लिए आवंटित कर रहे हैं (द्वारा '*' चिह्नित) एक पंक्ति पहुंच दी गई है " जे ", जिसे तब" पैरा "चर सेट करने के लिए प्रयोग किया जाता है। यदि यह लाइन पर केवल एक चीज है, तो है कि पहले पैरामीटर होने के लिए फैलता है हो आदेश निष्पादित है

%* 

, अन्य सभी इसे करने के लिए पारित कर दिया मानकों के साथ:

+0

यह तब विफल हो जाता है जब पहले तर्क में एक स्थान (उद्धृत) होता है, उदाहरण के लिए "पहला तर्क" दूसरा तीसरा '' तर्क 'पर पैरा सेट करता है दूसरा तीसरा' – EM0

5

आप वास्तव में सिर्फ यह कर सकते हैं । :)

1

एक और तरीका है एक subshell में ECHO को क्रियान्वित करने के बिना (लगभग 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 

समस्या यह है कि यदि पैरामीटर में रिक्त स्थान के साथ उद्धृत स्टिंग शामिल हैं, cmd.exe उन्हें उचित रूप से पार्स का उपयोग करने के लिए पार्स करेगा एस क्रमांकित तर्क (% 1), लेकिन उद्धरण उद्धरणों को अनदेखा करेंगे। यह विशिष्ट मामला, यदि पहले पैरामीटर में एक स्पेस या अधिक शामिल है, तो यह नुकसान पहुंचाएगा, जो कि काफी संभव है,% सीएमडी% पर विचार कर सकते हैं, उदाहरण के लिए, "सी: \ प्रोग्राम फ़ाइलें \ इंटरनेट एक्सप्लोरर \ 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% 

किसी भी तरह, मैंने देखा कि सवाल लंबे जवाब था, लेकिन लगा मैं डॉ चाहते मेरे दो सेंटों में सेशन करें क्योंकि यह कुछ ऐसा नहीं था जिसे मैंने नहीं देखा था, और क्योंकि यह जवाब था जब मुझे अंत में कुछ साल पहले ऐसा हुआ ... और "ओह ... दुह।" :)

+1

शिफ्ट% * इसलिए यह * सभी * मूल तर्क% run_me% में% 1 और% 2 सहित गुजरता है। स्वीकृत उत्तर के अनुसार "% * हमेशा सभी मूल मानकों में विस्तारित होगा, दुख की बात है।" – Naaff

0

मैं इस प्रश्न में आया, जबकि मुझे एक ही समस्या का सामना करना पड़ रहा था, लेकिन मैंने इसे एक अलग दृष्टिकोण का उपयोग करके हल किया। लूप का उपयोग करके इनपुट लाइन को फिर से बनाने के बजाय (जैसा कि @ जॉय द्वारा उत्तर में) मैंने इनपुट स्ट्रिंग से पहले पैरामीटर को हटा दिया।

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

बेशक, यह मानता है कि सभी पैरामीटर अलग हैं।

संबंधित मुद्दे

 संबंधित मुद्दे