내가 전화 스칼라에서 프로그램 쓰고 있어요에서 프로그램의 존재를 확인하는 방법 :. "SVN은"명령 줄에서 사용할 수있는 경우경로
Runtime.getRuntime().exec("svn ...")
내가 확인하려면 (즉 그것은 도달 PATH에 있음). 어떻게해야합니까?
는 PS : 내 프로그램은 윈도우에서 실행되도록 설계
내가 전화 스칼라에서 프로그램 쓰고 있어요에서 프로그램의 존재를 확인하는 방법 :. "SVN은"명령 줄에서 사용할 수있는 경우경로
Runtime.getRuntime().exec("svn ...")
내가 확인하려면 (즉 그것은 도달 PATH에 있음). 어떻게해야합니까?
는 PS : 내 프로그램은 윈도우에서 실행되도록 설계
내가 더 스칼라 프로그래머는 아니지만, 내가 어떤 언어로 어떻게 할 것인지, 단지 (리턴 코드를 확인하기 위해 'svn help
'같은 것을 실행하는 것입니다 그것은 SVN 실패하면 0 또는 1)에있어서의 간부 ... 경로에 있지 : P 관례
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("svn help");
int exitVal = proc.exitValue();
, 값 0은 정상 종료를 나타낸다.
원래 질문에 대해서는 FMF가 제시 한대로 존재하는지 확인합니다.
적어도 프로세스의 출력을 처리하고 사용 가능한 데이터를 읽어야 스트림이 가장자리에 채워지지 않도록해야한다는 점을 지적하고자합니다. 이렇게하면 프로세스가 차단됩니다.
이렇게하려면 proc.getInputStream() (System.out) 및 proc.getErrorStream() (System.err)을 사용하여 프로세스의 InputStream을 검색하고 다른 스레드에서 사용 가능한 데이터를 읽습니다.
이 일반적인 함정과 SVN은 잠재적으로 매우 offtopicness에 대한 downvote하지 말아 주시기 바랍니다 출력 꽤 만들 것이기 때문에 난 그냥 당신에게, 당신이 Cygwin에서 설치 한 경우)
먼저 "어떤 SVN 부를 수 ", 실행 경로에있는 경우 svn의 절대 경로를 반환하거나"which : no svn in (...) "을 반환합니다. "which"에 대한 호출은 exitValue가 발견되지 않으면 1을 리턴하고, 발견되면 0을 리턴합니다. FMF 세부 사항에서이 오류 코드를 점검 할 수 있습니다.
어쩌면 누군가가 자바 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()
로 교체 할 수 있습니다 - 그래서 당신은 정확한 실행 경로를 얻을 수 있습니다.
'Pattern.splitAsStream'을 사용하면 더 좋을 것입니다 ... –
이것을 시도하고 IDE (Eclipse를 사용하고 있습니다)에서 실행하면 내 환경 PATH에 경로가 추가 된 파일을 찾을 수 없습니다 변하기 쉬운. 그러나 실행 가능한 JRE를 만들어 터미널에서 실행하면 작동합니다. 따라서 터미널을 열 때 내 IDE 내에서 내 PATH가 내 PATH와 같지 않은 것 같습니다. 이 문제를 어떻게 해결할 수 있습니까? 코드를 테스트 할 때마다 runnable Jar를 만들지는 않을 것입니다. 감사! – skrilmps
Windows에서도 작동하지 않습니다. 'exec = java'를 설정하면 거짓 결과를 얻습니다. 하지만 cmd에서 'java'를 실행하면 히트가 발생합니다. – skrilmps
셀레늄은 셀레늄 3.1 이후 public
액세스 클래스 org.openqa.selenium.os.ExecutableFinder
에서 윈도우/리눅스/Mac 용 합리적으로 완벽하게 구현 될 모습이 (비추천 방법 org.openqa.selenium.os.CommandLine#find
를 통해 이전에는 접근). ASL 2.0입니다.
ExecutableFinder
은 Windows에서 PATHEXT
을 인식하지 못합니다. 하드 코딩 된 실행 파일 확장자 (.exe, .com, .bat) 세트 만 있습니다.
이제 공개됩니다. https://github.com/SeleniumHQ/selenium/blob/master/java/client/src/org/openqa/selenium/os/ExecutableFinder.java#L48 – gouessej
감사합니다. @gouessej. 아직 출시되지 않은 것 같습니다 : https://github.com/SeleniumHQ/selenium/blob/selenium-3.0.1/java/client/src/org/openqa/selenium/os/ExecutableFinder.java#L35 – seanf
이 코드는 Windows에서 "where"명령을 사용하고 다른 시스템에서는 "which"명령을 사용하여 시스템이 PATH에서 원하는 프로그램을 알고 있는지 확인합니다. 발견되면, 함수는 java.nio.file.Path를 프로그램에 리턴하고, 그렇지 않으면 널 (null)을 리턴합니다.
Windows 7 및 Linux Mint 17.3에서 Java 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"));
을 내 Windows 7 시스템에, 그것은 표시
C : \ WINDOWS \ system32를 \ notepad.exe를
그리고 Linux on :
System.out.println(SimulationUtils.lookForProgramInPath("psql"));
는/usr/빈/psql의
이 방법의 장점은 모든 플랫폼에서 작동해야하고 PATH 환경 변수를 구문 분석하거나 레지스트리보고 할 필요가 없습니다 것입니다. 원하는 프로그램이 발견 되더라도 절대로 호출되지 않습니다. 마지막으로 프로그램 확장을 알 필요가 없습니다. Windows의 gnuplot.exe와 Linux의 gnuplot은 모두 같은 코드에서 찾을 수 있습니다.
SimulationUtils.lookForProgramInPath("gnuplot")
개선을위한 제안은 환영합니다! 내 경험에
이것은 실제로 끔찍한 성능을 가지고 있습니다. 외부 프로세스 호출은 가능한 한 피해야합니다. – BullyWiiPlaza
@BullyWiiPlaza : 좋은 성능을 달성하는 것이 내 목표도 아니 었습니다. Windows/Linux/MacOS에서 작업하면서 더 빠를 수있는 방법이 있다면 언제든지 제안 해주십시오. BTW, 결과를 캐시 할 수 있습니다. 마지막으로 목표는 외부 프로세스를 호출하는 것입니다. 'svn' 호출은'where' 나'which' 호출보다 훨씬 느립니다. –
예, '드미트리 긴츠 부르그 (Gmitzburg Dmitry Ginzburg)'의 대답은 정말 좋습니다. 'where'는 상대적으로 큰 오버 헤드 (100-200ms 이상이 될 수 있습니다.)를 여러 번 호출하면 손에서 빠져 나갑니다. 난 그냥 내 눈에 띄게 느린 이유에 관해서는 이걸 깨달았다. – BullyWiiPlaza
종료 아닌지 단지 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;
}
내가 대신 'svn의 도움을 "의"svn을하는 "할 더 좋을 거라 생각 :
여기 도우미입니다. svn이 경로에 존재하는지 여부에 대한 적절한 반환 코드를 제공하지만 성공하면 svn 실행 파일에 대한 전체 경로도 가져옵니다. – Apreche
"which"는 Windows 명령이 아닙니다. – EMMERICH
"where는"Windows "의"which "입니다. –