पथ

2009-06-01 21 views
13

मैं स्केला में एक प्रोग्राम है जो फोन लिख रहा हूँ में एक कार्यक्रम के अस्तित्व की जांच कैसे करें:।पथ

Runtime.getRuntime().exec("svn ...") 

मैं जाँच करना चाहते हैं, तो "SVN" कमांडलाइन से उपलब्ध है (यानी यह पहुंचा जा सकता है पाथ में)। मैं यह कैसे कर सकता हूं?

पुनश्च: मेरे कार्यक्रम खिड़कियों पर चलाने के लिए डिज़ाइन किया गया है

उत्तर

13

मुझे कोई स्केला प्रोग्रामर हूँ, लेकिन मैं क्या किसी भी भाषा में करना होगा, बस वापसी कोड की जाँच करने के ('svn help' की तरह कुछ पर अमल करने के लिए है 0 या 1) कार्यकारी विधि का ... अगर यह SVN में विफल रहता है रास्ते में नहीं है: पी

Runtime rt = Runtime.getRuntime(); 
Process proc = rt.exec("svn help"); 
int exitVal = proc.exitValue(); 

परंपरा के मुताबिक, मान 0 सामान्य समाप्ति इंगित करता है।

+0

मुझे लगता है कि यह बेहतर होगा करने के लिए के बजाय "SVN मदद" "जो svn":

public static File checkAndGetFromPATHEnvVar(final String matchesExecutable) { String[] pathParts = System.getenv("PATH").split(File.pathSeparator); for (String pathPart : pathParts) { File pathFile = new File(pathPart); if (pathFile.isFile() && pathFile.getName().toLowerCase().contains(matchesExecutable)) { return pathFile; } else if (pathFile.isDirectory()) { File[] matchedFiles = pathFile.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return FileUtil.getFileNameWithoutExtension(pathname).toLowerCase().equals(matchesExecutable); } }); if (matchedFiles != null) { for (File matchedFile : matchedFiles) { if (FileUtil.canRunCmd(new String[]{matchedFile.getAbsolutePath()})) { return matchedFile; } } } } } return null; } 

यहाँ सहायक हैं। यह अभी भी उचित वापसी कोड देगा कि क्या पथ में svn मौजूद है या नहीं, लेकिन सफलता पर आपको svn निष्पादन योग्य के लिए पूर्ण-पथ भी मिल जाएगा। – Apreche

+5

"कौन" विंडोज कमांड नहीं है। – EMMERICH

+0

"कहां" विंडोज़ समतुल्य है "कौन" –

2

मूल प्रश्न मैं भी होने की जाँच चाहते हैं के रूप में ऍफ़एमऍफ़ सुझाव के संबंध में।

मैं यह भी कहना है कि आप इस प्रक्रिया के कम से कम उत्पादन, उपलब्ध आंकड़ों पढ़ने इसलिए धाराओं सीमा को भरा नहीं किया जाएगा संभालने के लिए होगा चाहते हैं। इससे प्रक्रिया को अवरुद्ध कर दिया जाएगा, अन्यथा।

ऐसा करने के लिए, proc.getInputStream() (System.out के लिए) और proc.getErrorStream() (System.err के लिए) का उपयोग करके प्रक्रिया के इनपुटस्ट्रीम को पुनर्प्राप्त करें और विभिन्न धागे में उपलब्ध डेटा पढ़ें।

क्योंकि यह एक आम ख़तरा है और SVN संभवतः काफी उत्पादन का एक सा पैदा करेगा तो offtopicness के लिए downvote नहीं करते कृपया मैं सिर्फ आपको बता;)

0

आप cygwin स्थापित किया है, तो पहले आपको कह सकते हैं "जो SVN ", जो निष्पादन योग्य पथ में है, या तो" sv: में कोई svn (...) "svn के पूर्ण पथ को वापस कर देगा। "कौन" कॉल करने के लिए कॉल 1 से बाहर निकल जाएगा यदि नहीं मिला, या 0 पाया जाता है। आप इस त्रुटि कोड को एफएमएफ विवरण के तरीके से देख सकते हैं।

13

हो सकता है कि किसी को जावा 8 समाधान में रुचि होगी:

String exec = <executable name>; 
boolean existsInPath = Stream.of(System.getenv("PATH").split(Pattern.quote(File.pathSeparator))) 
     .map(Paths::get) 
     .anyMatch(path -> Files.exists(path.resolve(exec))); 

वैसे, आप anyMatch(...)filter(...).findFirst() से बदल सकते हैं - तो आप सही निष्पादन योग्य पथ मिलेगा।

+0

आप 'Pattern.splitAsStream' के साथ बेहतर हो जाएंगे ... –

+0

जब मैं इसे आज़माता हूं और इसे अपने आईडीई (मैं ग्रहण का उपयोग कर रहा हूं) के अंदर चलाता हूं, तो यह उस फ़ाइल को नहीं ढूंढ सकता जिसने अपना पर्यावरण मेरे पथ में जोड़ा है चर। हालांकि, जब मैं इससे एक रनने योग्य जेआरई बनाता हूं और इसे अपने टर्मिनल से चलाता हूं, तो यह काम करता है। इसलिए मुझे संदेह है कि मेरे आईडीई के अंदर से मेरा पाथ मेरे पाथ के समान नहीं है जब मैं टर्मिनल खोलता हूं। मैं इसके पास कैसे आ सकता हूं? हर बार जब मैं कोड का परीक्षण करना चाहता हूं तो मैं एक रनने योग्य जार नहीं बनाऊंगा। धन्यवाद! – skrilmps

+0

मुझे विंडोज़ पर काम करने के लिए यह भी नहीं मिल रहा है। अगर मैं 'exec = java' सेट करता हूं तो मुझे झूठा परिणाम मिलता है। लेकिन अगर मैं cmd ​​से 'जावा' कहता हूं तो मुझे हिट मिलती है। – skrilmps

4

सेलेनियम क्या सेलेनियम 3.1 के बाद से public उपयोग के साथ वर्ग org.openqa.selenium.os.ExecutableFinder में विंडोज़/लिनक्स/मैक के लिए एक यथोचित पूरा कार्यान्वयन हो सकता है, लग रहा है है (पहले पदावनत विधि org.openqa.selenium.os.CommandLine#find के माध्यम से ही उपलब्ध)। हालांकि यह एएसएल 2.0 है।

ध्यान दें कि ExecutableFinder विंडोज पर PATHEXT नहीं समझता है - इसमें केवल निष्पादन योग्य फ़ाइल एक्सटेंशन (.exe, .com, .bat) का हार्ड-कोडेड सेट है।

+1

अब यह सार्वजनिक है: https://github.com/SeleniumHQ/selenium/blob/master/java/client/src/org/openqa/selenium/os/ExecutableFinder.java#L48 – gouessej

+0

धन्यवाद @ gouessej। ऐसा लगता है कि यह अभी तक रिलीज़ का हिस्सा नहीं है: https://github.com/SeleniumHQ/selenium/blob/selenium-3.0.1/java/client/src/org/openqa/selenium/os/ExecutableFinder.java#L35 – seanf

3

इस कोड का उपयोग करता है "कहाँ" विंडोज पर आदेश, और "जो" अन्य सिस्टम पर कमांड, अगर सिस्टम पथ में वांछित कार्यक्रम के बारे में जानता है की जाँच करने के। यदि पाया जाता है, तो फ़ंक्शन प्रोग्राम में java.nio.file.Path देता है, और अन्यथा शून्य।

मैं विंडोज 7 और लिनक्स टकसाल 17.3 पर जावा 8 के साथ यह परीक्षण किया गया।

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.util.logging.Logger; 


public class SimulationUtils 
{ 
    private final static Logger LOGGER = Logger.getLogger(SimulationUtils.class.getName()); 

    public static Path lookForProgramInPath(String desiredProgram) { 
     ProcessBuilder pb = new ProcessBuilder(isWindows() ? "where" : "which", desiredProgram); 
     Path foundProgram = null; 
     try { 
      Process proc = pb.start(); 
      int errCode = proc.waitFor(); 
      if (errCode == 0) { 
       try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) { 
        foundProgram = Paths.get(reader.readLine()); 
       } 
       LOGGER.info(desiredProgram + " has been found at : " + foundProgram); 
      } else { 
       LOGGER.warning(desiredProgram + " not in PATH"); 
      } 
     } catch (IOException | InterruptedException ex) { 
      LOGGER.warning("Something went wrong while searching for " + desiredProgram); 
     } 
     return foundProgram; 
    } 

    private static boolean isWindows() { 
     return System.getProperty("os.name").toLowerCase().contains("windows"); 
    } 
} 

इसका इस्तेमाल करने के लिए:

System.out.println(SimulationUtils.lookForProgramInPath("notepad")); 

मेरी विंडोज 7 प्रणाली पर, यह प्रदर्शित करता है:

C: \ Windows \ System32 \ notepad.exe

और लिनक्स पर:

System.out.println(SimulationUtils.lookForProgramInPath("psql")); 

/usr/bin/psql

इस विधि का लाभ यह है कि यह किसी भी मंच पर काम करना चाहिए और पथ वातावरण चर पार्स या रजिस्ट्री को देखने के लिए कोई आवश्यकता नहीं है है। वांछित कार्यक्रम कभी नहीं कहा जाता है, भले ही पाया जाता है। अंत में, प्रोग्राम एक्सटेंशन को जानने की आवश्यकता नहीं है। विंडोज और लिनक्स के तहत gnuplot के तहत gnuplot.exe दोनों एक ही कोड के द्वारा पाया जा होगा: सुधार के लिए

SimulationUtils.lookForProgramInPath("gnuplot") 

सुझावों का स्वागत है!

+0

यह वास्तव में भयानक प्रदर्शन है। जितनी ज्यादा हो सके बाहरी प्रक्रियाओं को बुलाया जाना चाहिए। – BullyWiiPlaza

+1

@ बुलीवेइप्लाज़ा: अच्छा, अच्छा प्रदर्शन प्राप्त करना मेरा लक्ष्य नहीं था। यदि आपको कोई विचार है कि विंडोज/लिनक्स/मैकोज़ में अभी भी काम करते समय यह तेज़ कैसे हो सकता है, तो कुछ भी सुझाव देने में संकोच न करें। बीटीडब्ल्यू, परिणाम कैश किया जा सकता है। अंत में, लक्ष्य बाहरी प्रक्रिया को कॉल करना है। कोई भी 'svn' कॉल शायद' कहां 'या' कौन सी कॉल 'से बहुत धीमी होगी। –

+0

हां, 'दिमित्री गिन्ज़बर्ग' द्वारा उपरोक्त उत्तर वास्तव में अच्छा है। 'जहां 'अपेक्षाकृत बड़ा ओवरहेड है (100 से 200ms से अधिक हो सकता है) और यदि आप इसे कई बार कहते हैं तो यह हाथ से बाहर हो जाता है। मुझे बस इस कोड में यह एहसास हुआ कि यह क्यों धीमा था। – BullyWiiPlaza

0

मेरे अनुभव में यह असंभव है सिर्फ ProcessBuilder के साथ एक कमांड बुला के माध्यम से विभिन्न प्रणालियों से अधिक बताती हैं कि यह बाहर निकालता है या नहीं (न Exceptions है और न ही लौट मूल्यों संगत प्रतीत)

तो यहाँ एक Java7 समाधान है कि PATH पर्यावरण परिवर्तक का पता चलता है और एक मिलान उपकरण के लिए देखता है। निर्देशिका अगर सभी फाइलों की जांच करेगा। matchesExecutable एक्सटेंशन और केस को अनदेखा करने वाले टूल का नाम होना चाहिए।

public static String getFileNameWithoutExtension(File file) { 
     String fileName = file.getName(); 
     int pos = fileName.lastIndexOf("."); 
     if (pos > 0) { 
      fileName = fileName.substring(0, pos); 
     } 
     return fileName; 
} 

public static boolean canRunCmd(String[] cmd) { 
     try { 
      ProcessBuilder pb = new ProcessBuilder(cmd); 
      pb.redirectErrorStream(true); 
      Process process = pb.start(); 
      try (BufferedReader inStreamReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { 
       while ((inStreamReader.readLine()) != null) { 
       } 
      } 
      process.waitFor(); 
     } catch (Exception e) { 
      return false; 
     } 
     return true; 
} 
संबंधित मुद्दे