विंडोज स्क्रिप्ट और लिनक्स बैश दोनों में चलने के लिए सिंगल स्क्रिप्ट?


96

क्या एक एकल स्क्रिप्ट फ़ाइल लिखना संभव है जो विंडोज (दोनों के रूप में .bat) और लिनक्स (बैश के माध्यम से) में निष्पादित होती है?

मैं दोनों के मूल सिंटैक्स को जानता हूं, लेकिन यह पता नहीं चला। यह शायद कुछ बैश के अस्पष्ट वाक्यविन्यास या कुछ विंडोज बैच प्रोसेसर गड़बड़ का फायदा उठा सकता है।

निष्पादित करने की कमांड अन्य स्क्रिप्ट को निष्पादित करने के लिए सिर्फ एक लाइन हो सकती है।

प्रेरणा विंडोज और लिनक्स दोनों के लिए सिर्फ एक ही एप्लीकेशन बूट कमांड है।

अद्यतन: सिस्टम की "मूल" शेल स्क्रिप्ट की आवश्यकता है कि इसे सही दुभाषिया संस्करण चुनने की आवश्यकता है, कुछ प्रसिद्ध पर्यावरण चर आदि के अनुरूप। अतिरिक्त वातावरण जैसे सिगविन स्थापित करना बेहतर नहीं है - मैं इस अवधारणा को रखना चाहूंगा " डाउनलोड करें और चलाएं ”।

विंडोज के लिए विचार करने वाली एकमात्र अन्य भाषा विंडोज स्क्रिप्टिंग होस्ट - डब्ल्यूएसएच है, जो 98 से डिफ़ॉल्ट रूप से पूर्व निर्धारित है।


9
पर्ल या पायथन में देखें। वे दोनों प्लेटफार्मों पर उपलब्ध भाषाओं की स्क्रिप्टिंग कर रहे हैं।
a_horse_with_no_name

groovy, अजगर, किसी को भी रूबी? stackoverflow.com/questions/257730/…
कल्पेश सोनी

ग्रूवी डिफ़ॉल्ट रूप से सभी प्रणालियों पर होना बहुत अच्छा होगा, मैं इसे शेल स्क्रिप्टिंग लैंग के रूप में ले जाऊंगा। शायद किसी दिन :)
ओंद्र raižka

1
इसे भी देखें: github.com/BYVoid/Batsh
डेव जार्विस

2
इसके लिए एक सम्मोहक उपयोग मामला है ट्यूटोरियल - लोगों को केवल यह बताने में सक्षम होने के लिए कि "इस छोटी सी स्क्रिप्ट को चलाएं" यह समझाने के लिए कि "यदि आप विंडोज पर हैं, तो इस छोटी स्क्रिप्ट का उपयोग करें, लेकिन यदि आप लिनक्स या मैक पर हैं, तो इसे आज़माएं इसके बजाय, जो मैंने वास्तव में परीक्षण नहीं किया है क्योंकि मैं विंडोज पर हूं। " अफसोस की बात है कि विंडोज cpमें अंतर्निहित यूनिक्स जैसी कमांड नहीं है , या इसके विपरीत, इसलिए दो अलग-अलग स्क्रिप्ट लिखना, यहां दिखाए गए उन्नत तकनीकों की तुलना में शैक्षणिक रूप से बेहतर हो सकता है।
क्वर्टी जू

जवाबों:


92

मैंने जो किया है वह cmd के लेबल सिंटैक्स का उपयोग टिप्पणी मार्कर के रूप में कर रहा है । लेबल वर्ण, एक कॉलन ( :), trueअधिकांश POSIXish गोले में समतुल्य है । यदि आप तुरंत किसी अन्य वर्ण द्वारा लेबल वर्ण का अनुसरण करते हैं जिसका उपयोग नहीं किया जा सकता है GOTO, तो आपकी cmdस्क्रिप्ट पर टिप्पणी करना आपके cmdकोड को प्रभावित नहीं करना चाहिए ।

हैक चरित्र अनुक्रम " :;" के बाद कोड की लाइनें डाल रहा है । यदि आप ज्यादातर एक-लाइनर स्क्रिप्ट लिख रहे हैं या, जैसा भी हो, shकई लाइनों के लिए एक लाइन लिख सकते हैं cmd, निम्नलिखित ठीक हो सकता है। यह मत भूलो कि किसी भी उपयोग को $?आपके अगले बृहदान्त्र से पहले होना चाहिए :क्योंकि 0 को :रीसेट करता $?है।

:; echo "Hi, I’m ${SHELL}."; exit $?
@ECHO OFF
ECHO I'm %COMSPEC%

रखवाली का एक बहुत ही वंचित उदाहरण $?:

:; false; ret=$?
:; [ ${ret} = 0 ] || { echo "Program failed with code ${ret}." >&2; exit 1; }
:; exit
ECHO CMD code.

अधिक लंघन के लिए एक और विचार cmdकोड का उपयोग करने के लिए है heredocs ताकि shव्यवहार करता है cmdएक अप्रयुक्त स्ट्रिंग और के रूप में कोड cmdयह व्याख्या करता है। इस मामले में, हम यह सुनिश्चित करते हैं कि हमारे हेरेडोक का सीमांकक दोनों उद्धृत किया गया है ( shजब इसके साथ चल रहा है तो इसकी सामग्री पर किसी भी प्रकार की व्याख्या करने से रोकना sh) और इसके साथ शुरू होता है :ताकि cmdकिसी भी अन्य रेखा की तरह शुरू हो जाए :

:; echo "I am ${SHELL}"
:<<"::CMDLITERAL"
ECHO I am %COMSPEC%
::CMDLITERAL
:; echo "And ${SHELL} is back!"
:; exit
ECHO And back to %COMSPEC%

आपकी आवश्यकताओं या कोडिंग शैली के आधार पर, इंटरलेसिंग cmdऔर shकोड समझ में नहीं आता है या नहीं हो सकता है। इस तरह के इंटरलेसिंग को करने के लिए हेरेडोक्स का उपयोग करना एक विधि है। हालाँकि, इसे GOTOतकनीक के साथ बढ़ाया जा सकता है :

:<<"::CMDLITERAL"
@ECHO OFF
GOTO :CMDSCRIPT
::CMDLITERAL

echo "I can write free-form ${SHELL} now!"
if :; then
  echo "This makes conditional constructs so much easier because"
  echo "they can now span multiple lines."
fi
exit $?

:CMDSCRIPT
ECHO Welcome to %COMSPEC%

सार्वभौमिक टिप्पणियां, ज़ाहिर है, चरित्र अनुक्रम के साथ की जा सकती हैं : #या :;#। अंतरिक्ष या अर्धविराम आवश्यक हैं क्योंकि यह एक कमांड नाम का हिस्सा shमाना जाता #है यदि यह किसी पहचानकर्ता का पहला चरित्र नहीं है। उदाहरण के लिए, आप GOTOअपने कोड को विभाजित करने की विधि का उपयोग करने से पहले अपनी फ़ाइल की पहली पंक्तियों में सार्वभौमिक टिप्पणियां लिखना चाह सकते हैं । तब आप अपने पाठक को सूचित कर सकते हैं कि आपकी लिपि को इतनी विषमता से क्यों लिखा गया है:

: # This is a special script which intermixes both sh
: # and cmd code. It is written this way because it is
: # used in system() shell-outs directly in otherwise
: # portable code. See /programming/17510688
: # for details.
:; echo "This is ${SHELL}"; exit
@ECHO OFF
ECHO This is %COMSPEC%

इस प्रकार, कुछ विचारों और तरीकों को पूरा करने के लिए shऔर cmdगंभीर स्क्रिप्ट के बिना असंगत स्क्रिप्ट, जहां तक ​​मुझे पता है (और cmdआउटपुट के बिना '#' is not recognized as an internal or external command, operable program or batch file.)।


5
ध्यान दें कि इसके लिए स्क्रिप्ट का .cmdविस्तार होना आवश्यक है, अन्यथा यह विंडोज में नहीं चलेगा। क्या कोई वर्कअराउंड है?
इविवि

1
यदि आप बैच फ़ाइलों को लिख रहे हैं, तो मैं उन्हें केवल नाम देने .cmdऔर उन्हें निष्पादन योग्य चिह्नित करने की सलाह दूंगा। इस तरह, विंडोज या यूनिक्स पर डिफ़ॉल्ट शेल से स्क्रिप्ट निष्पादित करना काम करेगा (केवल बैश के साथ परीक्षण किया गया)। चूँकि मैं cmd ​​की शिकायत किए बिना शेबबैंग को शामिल करने के तरीके के बारे में नहीं सोच सकता, इसलिए आपको हमेशा शेल के माध्यम से स्क्रिप्ट का आह्वान करना चाहिए। यानी, का उपयोग करना सुनिश्चित करें execlp()या execvp()(मुझे लगता system()है कि यह आपके लिए "सही" तरीका है) के बजाय execl()या execv()(ये बाद वाले कार्य केवल शेलबैंग के साथ स्क्रिप्ट पर काम करेंगे क्योंकि वे सीधे ओएस पर जाते हैं)।
बिंकी

मैंने फ़ाइल एक्सटेंशन के बारे में चर्चा छोड़ दी क्योंकि मैं स्वतंत्र बैच फ़ाइलों के बजाय शेलआउट (जैसे, <Exec/>MSBuild टास्क ) में अपना पोर्टेबल कोड लिख रहा था । हो सकता है कि अगर भविष्य में मेरे पास कुछ समय हो तो मैं इन टिप्पणियों में जानकारी के साथ उत्तर को अपडेट करूंगा ...
binki

23

आप यह कोशिश कर सकते हैं:

#|| goto :batch_part
 echo $PATH
#exiting the bash part
exit
:batch_part
 echo %PATH%

संभवतः आपको /r/nयूनिक्स शैली के बजाय एक नई लाइन के रूप में उपयोग करने की आवश्यकता होगी। यदि मुझे याद है कि यूनिक्स नई लाइन सही है तो स्क्रिप्ट द्वारा नई लाइन के रूप में व्याख्या नहीं की जाती है। एक .batतरीका यह है #.exeकि रास्ते में एक फ़ाइल बनाई जाए जिसमें कुछ भी नहीं होता है मेरे जवाब के अनुसार यहां समान तरीके: क्या अस्थायी फ़ाइल का उपयोग किए बिना बैच फ़ाइल के भीतर VBScript को एम्बेड और निष्पादित करना संभव है?

संपादित करें

Binki के जवाब लगभग पूर्ण है, लेकिन अभी भी सुधार किया जा सकता:

:<<BATCH
    @echo off
    echo %PATH%
    exit /b
BATCH

echo $PATH

यह फिर से :ट्रिक और मल्टी लाइन टिप्पणी का उपयोग करता है। cmd.exe (विंडोज़ 10 पर कम से कम) की तरह काम करता है बिना यूनिक्स शैली वाले ईओएल के साथ समस्याओं के बिना काम करता है ताकि यह सुनिश्चित हो सके कि आपकी स्क्रिप्ट को लिनक्स प्रारूप में परिवर्तित किया गया है। (इसी दृष्टिकोण को यहाँ और यहाँ पहले भी देखा जा चुका है )। हालांकि शेलबैंग का उपयोग करना अब भी बेमानी उत्पादन होगा ...


3
/r/nलाइनों के अंत में बैश स्क्रिप्ट में कई सिरदर्द पैदा हो जाएंगे जब तक कि आप प्रत्येक लाइन को #(यानी #/r/n) के साथ समाप्त नहीं करते हैं - इस तरह से \rवसीयत को टिप्पणी के हिस्से के रूप में माना जाएगा और अनदेखा किया जाएगा।
गॉर्डन डेविसन

2
दरअसल, मुझे लगता है कि कमांड के द्वारा # 2>NUL & ECHO Welcome to %COMSPEC%.त्रुटि को छिपाने के लिए प्रबंधित #नहीं किया जा रहा है cmd। यह तकनीक उपयोगी है जब आपको एक स्टैंडअलोन लाइन लिखने की आवश्यकता होती है जिसे केवल cmd(जैसे, ए Makefile) द्वारा निष्पादित किया जाएगा ।
बिंकी b ’at१४

11

मैं टिप्पणी करना चाहता था, लेकिन फिलहाल केवल एक उत्तर जोड़ सकता हूं।

दी गई तकनीक उत्कृष्ट हैं और मैं उनका उपयोग भी करता हूं।

ऐसी फ़ाइल को बनाए रखना कठिन है, जिसमें दो प्रकार के लाइन ब्रेक हों, जो कि /nबैश भाग के /r/nलिए और विंडोज़ भाग के लिए हों। अधिकांश संपादक कोशिश करते हैं और यह अनुमान लगाकर कि आप किस तरह की फ़ाइल का संपादन कर रहे हैं, एक आम लाइन ब्रेक योजना लागू करते हैं। साथ ही इंटरनेट पर फ़ाइल को स्थानांतरित करने के अधिकांश तरीके (विशेष रूप से एक पाठ या स्क्रिप्ट फ़ाइल के रूप में) लाइन के टूटने की गड़बड़ी करेंगे, इसलिए आप एक तरह की लाइन ब्रेक के साथ शुरू कर सकते हैं और दूसरे के साथ समाप्त हो सकते हैं। यदि आपने लाइन ब्रेक के बारे में धारणा बनाई है और फिर अपनी स्क्रिप्ट किसी और को उपयोग करने के लिए दी है तो वे पा सकते हैं कि यह उनके लिए काम नहीं करता है।

अन्य समस्या नेटवर्क माउंटेड फ़ाइल सिस्टम (या सीडी) है जो विभिन्न सिस्टम प्रकारों के बीच साझा की जाती है (विशेषकर जहां आप उपयोगकर्ता के लिए उपलब्ध सॉफ़्टवेयर को नियंत्रित नहीं कर सकते हैं)।

इसलिए प्रत्येक को (प्रत्येक ) के अंत में एक टिप्पणी डालकर डॉस लाइन ब्रेक का उपयोग करना चाहिए /r/nऔर डीओएस से बाश स्क्रिप्ट की रक्षा करनी चाहिए । आप बैश में लाइन निरंतरता का भी उपयोग नहीं कर सकते क्योंकि उन्हें तोड़ने का कारण होगा।/r#/r

इस तरह जो भी स्क्रिप्ट का उपयोग करता है, और जो भी वातावरण में है, वह तब काम करेगा।

मैं इस विधि का उपयोग पोर्टेबल मेकफाइल्स बनाने के साथ करता हूं!


6

उपरोक्त उत्तरों के विपरीत, बैश 4 और विंडोज 10 के साथ कोई त्रुटि या त्रुटि संदेश के बिना निम्नलिखित मेरे लिए काम करता है। मैं फ़ाइल का नाम "जो भी। cmd" करता हूं, chmod +xइसे लिनक्स में निष्पादन योग्य बनाने के लिए करता हूं , और इसे dos2unixबैश को शांत रखने के लिए यूनिक्स लाइन एंडिंग ( ) है।

:; if [ -z 0 ]; then
  @echo off
  goto :WINDOWS
fi

if [ -z "$2" ]; then
  echo "usage: $0 <firstArg> <secondArg>"
  exit 1
fi

# bash stuff
exit

:WINDOWS
if [%2]==[] (
  SETLOCAL enabledelayedexpansion
  set usage="usage: %0 <firstArg> <secondArg>"
  @echo !usage:"=!
  exit /b 1
)

:: windows stuff

3

आप चर साझा कर सकते हैं:

:;SET() { eval $1; }

SET var=value

:;echo $var
:;exit
ECHO %var%

2

एक ही स्क्रिप्ट पर bashऔर इसके cmdसाथ अलग-अलग कमांड निष्पादित करने के कई तरीके हैं ।

cmd:;अन्य उत्तर में उल्लिखित लाइनों को अनदेखा करेंगे। यदि अगली पंक्ति कमांड के साथ समाप्त होती है, तो यह अगली पंक्ति को भी अनदेखा करेगा rem ^, क्योंकि ^चरित्र लाइन ब्रेक से बच जाएगा और अगली पंक्ति को टिप्पणी के रूप में माना जाएगा rem

लेने के लिए के रूप में bashउपेक्षा cmdलाइनों, एक से अधिक तरीके हैं। मैंने ऐसा करने के कुछ तरीके ईजाद किए हैं जो बिना cmdआज्ञा तोड़े :

गैर-मौजूद #आदेश (अनुशंसित नहीं)

यदि स्क्रिप्ट चलने #पर कोई आदेश उपलब्ध नहीं cmdहै, तो हम यह कर सकते हैं:

# 2>nul & echo Hello cmd! & rem ^
echo 'Hello bash!' #

#की शुरुआत में चरित्र cmdलाइन बनाता है bashएक टिप्पणी के रूप में है कि लाइन का इलाज।

#के अंत में चरित्र bashलाइन बाहर टिप्पणी करने के लिए प्रयोग किया जाता है \r, चरित्र के रूप में ब्रायन Tompsett में बताया उसके जवाब । इसके बिना, bashयदि फ़ाइल में \r\nलाइन की समाप्ति आवश्यक है, तो एक त्रुटि होगी cmd

ऐसा करने के बाद # 2>nul, हम cmdकुछ गैर-मौजूद #कमांड की त्रुटि को अनदेखा करने के लिए ट्रिक कर रहे हैं , जबकि अभी भी कमांड को निष्पादित किया जा रहा है।

यदि कोई #कमांड उपलब्ध है PATHया यदि आपके पास उपलब्ध कमांड पर कोई नियंत्रण नहीं है, तो इस समाधान का उपयोग न करें cmd


चरित्र echoको अनदेखा करने के लिए उपयोग करना#cmd

हम इसका उपयोग echoआउटपुट के साथ कर सकते हैं, जो कि इस क्षेत्र पर टिप्पणी करने के लिए cmdकमांड को पुनर्निर्देशित करता bashहै:

echo >/dev/null # >nul & echo Hello cmd! & rem ^
echo 'Hello bash!' #

चूंकि #चरित्र का कोई विशेष अर्थ नहीं है cmd, इसलिए इसे पाठ के एक भाग के रूप में माना जाता है echo। हमें बस इतना करना था कि echoकमांड के आउटपुट को रीडायरेक्ट करें और उसके बाद अन्य कमांड डालें।


खाली #.batफाइल

echo >/dev/null # 1>nul 2> #.bat
# & echo Hello cmd! & del #.bat & rem ^
echo 'Hello bash!' #

echo >/dev/null # 1>nul 2> #.batलाइन एक खाली बनाता है #.batफ़ाइल जबकि पर cmd(या की जगह मौजूदा #.bat, यदि कोई हो), और कुछ भी नहीं है, जबकि पर करता है bash

इस फ़ाइल का उपयोग उस cmdपंक्ति (पंक्तियों) द्वारा किया जाएगा, जो कि कुछ अन्य #कमांड पर होती है, भले ही उसका अनुसरण करती हो PATH

del #.batपर आदेश cmdविशिष्ट कोड बनाया गया था उस फ़ाइल को हटाता है। आपको केवल अंतिम cmdपंक्ति पर यह करना होगा ।

यदि कोई #.batफ़ाइल आपके वर्तमान कार्य निर्देशिका पर हो सकती है, तो इस समाधान का उपयोग न करें , क्योंकि वह फ़ाइल मिटा दी जाएगी।


Recomended: यहाँ-डॉक्युमेंट का उपयोग करके cmdकमांड्स को अनदेखा करनाbash

:; echo 'Hello bash!';<<:
echo Hello cmd! & ^
:

लाइन ^के अंत में चरित्र को रखकर cmdहम लाइन ब्रेक से बच रहे हैं, और :यहाँ-दस्तावेज़ के सीमांकक के रूप में उपयोग करके , सीमांकक रेखा सामग्री का कोई प्रभाव नहीं पड़ेगा cmd। इस तरह, लाइन खत्म होने के cmdबाद ही अपनी लाइन को अंजाम देंगे :, जैसा व्यवहार होगा bash

यदि आप दोनों प्लेटफार्मों पर कई लाइनें रखना चाहते हैं और केवल ब्लॉक के अंत में उन्हें निष्पादित करते हैं, तो आप ऐसा कर सकते हैं:

:;( #
  :;  echo 'Hello'  #
  :;  echo 'bash!'  #
:; );<<'here-document delimiter'
(
      echo Hello
      echo cmd!
) & rem ^
here-document delimiter

जब तक cmdवास्तव में कोई रेखा नहीं है here-document delimiter, तब तक इस समाधान को काम करना चाहिए। आप here-document delimiterकिसी अन्य पाठ में बदल सकते हैं ।


सभी प्रस्तुत समाधानों में, कमांड को केवल अंतिम पंक्ति के बाद निष्पादित किया जाएगा , यदि वे दोनों प्लेटफार्मों पर एक ही काम करते हैं, तो उनके व्यवहार को सुसंगत बनाते हैं।

उन समाधानों \r\nको लाइन ब्रेक के साथ फाइलों में सहेजा जाना चाहिए , अन्यथा वे काम नहीं करेंगे cmd


देर से बेहतर कभी नहीं ... इससे मुझे अन्य उत्तरों की तुलना में अधिक मदद मिली। धन्यवाद!!
ए-डिड्डी

2

पिछले उत्तर सभी विकल्पों को बहुत कवर करते हैं और मुझे बहुत मदद करते हैं। मैं यहाँ इस उत्तर को शामिल कर रहा हूँ बस उसी तंत्र को प्रदर्शित करने के लिए जिसका उपयोग मैंने बैश स्क्रिप्ट और विंडोज सीएमडी स्क्रिप्ट दोनों को एक ही फाइल में शामिल करने के लिए किया था।

LinuxWindowsScript.bat

echo >/dev/null # >nul & GOTO WINDOWS & rem ^
echo 'Processing for Linux'

# ***********************************************************
# * NOTE: If you modify this content, be sure to remove carriage returns (\r) 
# *       from the Linux part and leave them in together with the line feeds 
# *       (\n) for the Windows part. In summary:
# *           New lines in Linux: \n
# *           New lines in Windows: \r\n 
# ***********************************************************

# Do Linux Bash commands here... for example:
StartDir="$(pwd)"

# Then, when all Linux commands are complete, end the script with 'exit'...
exit 0

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

:WINDOWS
echo "Processing for Windows"

REM Do Windows CMD commands here... for example:
SET StartDir=%cd%

REM Then, when all Windows commands are complete... the script is done.

सारांश

लिनक्स में

पहली पंक्ति ( echo >/dev/null # >nul & GOTO WINDOWS & rem ^) को नजरअंदाज कर दिया जाएगा और स्क्रिप्ट को exit 0निष्पादित होने तक तुरंत प्रत्येक पंक्ति के माध्यम से प्रवाह होगा । एक बार exit 0पहुंच जाने के बाद , स्क्रिप्ट निष्पादन समाप्त हो जाएगा, इसके नीचे विंडोज कमांडों की अनदेखी होगी।

विंडोज में

पहली पंक्ति GOTO WINDOWSकमांड को निष्पादित करेगी , लिनक्स कमांडों को तुरंत इसे फॉलो करते हुए और :WINDOWSलाइन पर निष्पादन जारी रखें ।

विंडोज में कैरिज रिटर्न्स निकालना

चूंकि मैं इस फाइल को विंडोज में एडिट कर रहा था, इसलिए मुझे व्यवस्थित रूप से लिनक्स कमांड से गाड़ी के रिटर्न (\ r) को निकालना पड़ा या फिर बैश भाग को चलाते समय मुझे असामान्य परिणाम मिले। ऐसा करने के लिए, मैंने नोटपैड ++ में फ़ाइल खोली और निम्न कार्य किया:

  1. लाइन पात्रों के अंत देखने के लिए विकल्प चालू करें ( View> Show Symbol> Show End of Line)। कैरिज रिटर्न फिर CRपात्रों के रूप में दिखाई देगा ।

  2. एक खोज और बदलें ( Search> Replace...) करें और Extended (\n, \r, \t, \0, \x...)विकल्प की जाँच करें ।

  3. फ़ील्ड \rमें टाइप करें Find what :और फ़ील्ड को खाली करें Replace with :ताकि इसमें कुछ भी न हो।

  4. फ़ाइल के शीर्ष पर शुरू, Replaceबटन पर क्लिक करें जब तक कि सभी गाड़ी के रिटर्न ( CR) वर्ण शीर्ष लिनक्स भाग से हटा दिए गए हों। CRWindows भाग के लिए गाड़ी वापसी ( ) वर्णों को छोड़ना सुनिश्चित करें ।

इसका परिणाम यह होना चाहिए कि प्रत्येक लिनक्स कमांड सिर्फ एक लाइन फीड ( LF) में समाप्त होता है और प्रत्येक विंडोज कमांड एक कैरिज रिटर्न और लाइन फीड ( CR LF) में समाप्त होता है ।


1

मैं इस तकनीक का उपयोग रन करने योग्य जार फ़ाइलों को बनाने के लिए करता हूं। चूंकि जिपर / जिप फाइल जिप हेडर पर शुरू होती है, इसलिए मैं इस फाइल को शीर्ष पर चलाने के लिए एक सार्वभौमिक स्क्रिप्ट रख सकता हूं:

#!/usr/bin/env sh
@ 2>/dev/null # 2>nul & echo off
:; alias ::=''
:: exec java -jar $JAVA_OPTS "$0" "$@"
:: exit
java -jar %JAVA_OPTS% "%~dpnx0" %*
exit /B
  • पहली पंक्ति cmd में गूँजती है और श पर कुछ भी प्रिंट नहीं करती है। ऐसा इसलिए है क्योंकि @sh में एक त्रुटि होती है जिसे पाइप किया जाता है /dev/nullऔर उसके बाद एक टिप्पणी शुरू होती है। Cmd पर पाइप /dev/nullविफल हो जाता है क्योंकि फ़ाइल विंडोज़ पर पहचानी नहीं जाती है, लेकिन चूंकि विंडोज़ #एक टिप्पणी के रूप में पता नहीं लगाता है कि त्रुटि को पाइप किया गया है nul। तब यह एक गूंज करता है। क्योंकि यह पूरी लाइन पूर्ववर्ती है, @इस पर cmd का प्रिंटेट नहीं मिलता है।
  • दूसरा एक परिभाषित करता है ::, जो शिम में टिप्पणी करता है , शूप में नहीं। यह लाभ है कि ::करने के $?लिए रीसेट नहीं करता है 0। यह " :;एक लेबल है" चाल का उपयोग करता है ।
  • अब मैं sh कमांड को प्रीपेन्ड कर सकता हूं ::और उन्हें cmd ​​में नजरअंदाज किया जाता है
  • पर :: exitश स्क्रिप्ट समाप्त होता है और मैं cmd आदेशों लिख सकते हैं
  • Cmd में केवल पहली पंक्ति (shebang) समस्याग्रस्त है क्योंकि यह प्रिंट होगी command not found। आपको खुद को तय करना होगा कि आपको इसकी आवश्यकता है या नहीं।

0

मुझे अपने कुछ पायथन पैकेज स्थापित स्क्रिप्ट के लिए इसकी आवश्यकता थी। श और बैट फाइल के बीच ज्यादातर चीजें समान होती हैं लेकिन एरर हैंडलिंग जैसी कुछ चीजें अलग होती हैं। ऐसा करने का एक तरीका इस प्रकार है:

common.inc
----------
common statement1
common statement2

फिर आप इसे बैश स्क्रिप्ट से बुलाते हैं:

linux.sh
--------
# do linux specific stuff
...
# call common code
source common.inc

Windows बैच फ़ाइल कुछ इस प्रकार है:

windows.bat
-----------
REM do windows specific things
...
# call common code
call common.inc


-6

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


5
ऐसा लगता है कि उन उपकरणों का एक सकल दुरुपयोग है। यदि आप वास्तविक प्रश्न (देशी शेल में चल रहा है) से बचना चाहते हैं तो आपको एक सार्वभौमिक स्क्रिप्टिंग भाषा का सुझाव देना चाहिए, जैसे कि अजगर, न कि एक बिल्ड टूल, जो एक उचित स्क्रिप्टिंग भाषा के प्रतिस्थापन के रूप में दुरुपयोग होने में सक्षम होने के लिए होता है।
आर्टऑफवर्फ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.