2012-01-09 9 views
11

मैं तय करने के लिए एक सबसे कारगर तरीका में देख रहा हूँ:जावा, Runtime.exec या ProcessBuilder: फ़ाइल कैसे खोल या बाइनरी जानती है?

  • मैं खोल निष्पादन
  • यदि हाँ साथ उपयोगकर्ता द्वारा प्रदान की कमांड लाइन, कि निष्पादन योग्य क्या होगा preprend चाहिए? (/ bin/sh?/usr/bin/kl?/usr/bin/ksh? c: /../ cmd.exe?)

यह ज्ञात है कि जावा से एक शेल स्क्रिप्ट शुरू करने के लिए किसी को चाहिए बजाय खोल शुरू:

ProcessBuilder pb = new ProcessBuilder("/bin/sh", "script.sh", "arg1", "arg2); 

शुरू करने के लिए एक द्विआधारी एक द्विआधारी ही शुरू कर देना चाहिए:

ProcessBuilder pb = new ProcessBuilder("/bin/sh", "/path/binary", "arg1", "arg2); 
(sh: cannot execute binary file) 
:

ProcessBuilder pb = new ProcessBuilder("/path/binary", "arg1", "arg2); 

एक द्विआधारी खोल के साथ क्रियान्वित किया जाता है, तो यह एक त्रुटि पैदा करता है

ProcessBuilder pb = new ProcessBuilder("script.sh", "arg1", "arg2); 
(error 2: file not found) 

मैं एक स्थिति में हूँ जहाँ मेरे आवेदन पता नहीं है यह क्या है, शुरू होता है बाइनरी या एक स्क्रिप्ट: एक खोल स्क्रिप्ट खोल द्विआधारी बिना निष्पादित किया जाता है

हैं, तो यह एक त्रुटि पैदा करता है।

प्रारंभिक एप्लिकेशन एक ईवेंट हैंडलर अंतिम उपयोगकर्ता प्रदान करता है। यह यूनिक्स के तहत निष्पादित एक शेल स्क्रिप्ट हो सकता है; लेकिन यह विंडोज के तहत * .cmd हो सकता है, या कुछ अस्पष्ट प्लेटफ़ॉर्म के तहत निष्पादित एक पर्ल स्क्रिप्ट हो सकती है। यह जावा है, आखिरकार।

मेरा पहला निष्पक्ष प्रयास खोल के साथ कमांड लाइन शुरू करना था, और देखें कि यह काम करता है या नहीं। यदि नहीं, तो इसे बाइनरी के रूप में निष्पादित करने का प्रयास करें।

यह बदसूरत और जोखिम भरा है: मंच के कुछ अज्ञात संयोजन के तहत और दूसरा भाग अभी भी स्क्रिप्ट निष्पादित कर सकता है, दूसरी बार, अप्रत्याशित परिणामों के साथ।

इसके अलावा, मैं यह नहीं बता सकता कि स्क्रिप्ट ठीक क्यों शुरू हुई और जब मैं इसे शुरू नहीं कर सकता तब से कुछ समस्या के कारण विफल रहा।

सबसे अच्छी बात मैं अब पर विचार कर रहा हूँ है:

  • स्क्रिप्ट पढ़ें और किसी भी गंदा बाइट्स
  • के लिए देखें, तो पाया, यह एक द्विआधारी
  • यदि नहीं मानते हैं, जोड़ने/bin/sh (या cmd.exe अगर विंडोज के तहत)

कृपया सलाह दें कि आपके मन में कोई बेहतर विचार है या नहीं।

अद्यतन/आंशिक समाधान

जो कोई मेरे साथ अपने विचारों को साझा करने के लिए धन्यवाद।

बाहर कर देता है, मैं अपने आप को और इंटरनेट :)

यह पहले जोड़ें करने के लिए है कि उपलब्ध कराने के उपयोगकर्ता के प्रवेश किया कमांड लाइन से पहले द्विआधारी करेगा की आवश्यकता नहीं है के बाकी भ्रमित हो:

  1. स्क्रिप्ट पथ में है
  2. (यूनिक्स के लिए) स्क्रिप्ट निष्पादन
  3. लिपि (यूनिक्स के लिए) # है!/path/to/दुभाषिया है

जबकि मैं अपने कोड का परीक्षण कर रहा था, इन शर्तों में से एक या एक अन्य मुलाकात नहीं हुई थी। :-(

खरोंच स्क्रिप्ट से ध्यान से परीक्षण प्रदर्शन कर मार डाला हो जाने के बाद।

प्वाइंट 3 केवल उपयोगकर्ता द्वारा किया जा सकता है, और प्रयोक्ता मैनुअल में प्रलेखित किया जाना है।

कारण जिस तरह से इन स्क्रिप्ट को लक्ष्य प्रणाली में प्रचारित किया जाता है, वे निष्पादन योग्य नहीं हो सकते हैं और हो सकता है कि वे पाथ में न हों।

एकमात्र रास्ता जिसकी मैं परवाह करता हूं वह सापेक्ष है, इसलिए किसी भी सापेक्ष पथ पर // को प्रीपेड करना पर्याप्त है

वें बनाना यूनिक्स (और किसी भी अन्य मंच) के तहत निष्पादन योग्य ई स्क्रिप्ट एक चुनौती है। यह काम नहीं है। इसके सामने रखकर/bin/sh मदद कर सकता है, लेकिन अगर मुझे सोलारिस के ठीक नीचे याद है तो खोल एक निष्पादन योग्य स्क्रिप्ट निष्पादित नहीं करेगा।

मैं इस सप्ताह के अंत में एक और अपडेट पोस्ट करूंगा।

+1

क्या आपके शेल स्क्रिप्ट में शीर्ष पर एक उपयुक्त शेबांग लाइन ('#!') है? यदि ऐसा है, तो आप बस कर्नेल से इसे चलाने के लिए कह सकते हैं (जब तक यह '+ x' निष्पादन योग्य है) इस बारे में चिंतित किए बिना कि किस कमांड दुभाषिया की आवश्यकता हो सकती है। –

+0

मुझे नहीं पता। स्क्रिप्ट अंतिम उपयोगकर्ताओं से आता है, सॉफ्टवेयर के साथ आपूर्ति नहीं की जाती है। –

उत्तर

2

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

3

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

ProcessBuilder pb = new ProcessBuilder("script.sh", "arg1", "arg2); 
(error 2: file not found) 

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

यदि स्क्रिप्ट वर्तमान निर्देशिका में है तो आपको आगे ./ जोड़ने की आवश्यकता है। यदि आप निष्पादन योग्य के लिए कोई स्पष्ट पथ नहीं डालते हैं तो निष्पादन योग्य को आपके $PATH पर्यावरण चर में निर्देशिकाओं में से एक में रहना चाहिए। वर्तमान निर्देशिका . आमतौर पर डिफ़ॉल्ट रूप से $PATH में शामिल है।

ProcessBuilder pb = new ProcessBuilder("./script.sh", "arg1", "arg2); 

स्क्रिप्ट नाम एक उपयोगकर्ता के आपूर्ति मूल्य है तो मैं उपयोगकर्ता पर इस आवश्यकता को लेवी होगा - आप उनके लिए ./ जोड़ सकता है, लेकिन आम तौर पर यूनिक्स कार्यक्रमों भी उपयोगी किया जा रहा से बचने के लिए प्रयास करें। अगर वे ./ डालना भूल जाते हैं तो यह उनकी समस्या है!

+0

मेरे मस्तिष्क को बल देने के लिए धन्यवाद। दरअसल, ./script कम से कम आंशिक रूप से मदद करता है। –

0

ProcessBuilder pb = new ProcessBuilder("/bin/sh", "/path/binary", "arg1", "arg2); (sh: cannot execute binary file)

ProcessBuilder PB पर = नए ProcessBuilder ("/ bin/श", "-c" "/ path/बाइनरी", "ARG1", "ARG2); (श: नहीं कर सकते बाइनरी फ़ाइल निष्पादित)

एक विकल्प उपयोगकर्ताओं से एक और तर्क (शायद ज्ञात मानों की सूची से के रूप में दुभाषिया पथ) स्वीकार करना है।

(यह हो सकता था एक टिप्पणी। मैं स्वरूपण नहीं मिल सका दाएं)

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