2012-10-13 2 views
8

Possible Duplicate:
Executing a shell script inside a jar file. How to extract?내가 '엔진'패키지 내에서 내 JAR 파일로 패키지 쉘 스크립트가 JAR

내에서 쉘 스크립트 번들을 실행 자바는.

내 프로그램에서 Process 및 ProcessBuilder를 사용하여 쉘 명령을 실행 중입니다. 이 모든 것이 잘 작동합니다.

내 컴퓨터에서 쉘 스크립트 경로를 지정하면 프로그램이 정상적으로 작동합니다. 그러나 나는 내 JAR로 쉘 스크립트를 패키지하고 이런 식으로 액세스하는 경우 :이 수 없습니다 생각하기 시작하고

java.io.IOException: Cannot run program "file:/Users/USERNAME/Desktop/Application-Name.jar!/engine/shell-script.sh": error=2, No such file or directory 
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:460) 
    at java.lang.Runtime.exec(Runtime.java:593) 
    at java.lang.Runtime.exec(Runtime.java:431) 
    at java.lang.Runtime.exec(Runtime.java:328) 
    at engine.Download$1.run(Download.java:39) 
    at java.lang.Thread.run(Thread.java:680) 
Caused by: java.io.IOException: error=2, No such file or directory 
    at java.lang.UNIXProcess.forkAndExec(Native Method) 
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:53) 
    at java.lang.ProcessImpl.start(ProcessImpl.java:91) 
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:453) 
    ... 5 more 

: 프로그램을

scriptLocation = this.getClass().getResource("/engine/shell-script.sh").toString(); 

그리고 실행 한 후 나는 다음과 같은 오류가 발생합니다 이 쉘 스크립트를 응용 프로그램의 일부로 제공하고 싶습니다. 수행 할 수 있습니까? 사전 모두에

감사합니다.

======== UPDATE는 ==========

나는 결국이 문제를 해결했다. 쉘은 JAR 번들 내에서 스크립트를 실행할 수 없으며 Java가 아니라 쉘입니다.

자바는 createTempFile() 메소드 (애플리케이션이 종료되면 파일을 삭제할 수있는 옵션 포함)를 호출하고 액세스하여 액세스하려는 JAR 번들 내에 파일을 작성합니다. 이 임시 파일에. 그런 다음 로컬 파일 시스템에 쉘 스크립트가 있으며 스크립트를 실행할 수 있습니다.

답변

4

그것 :

$ unzip -p a.zip a.sh | bash 

을 자바 프로그램에서 다음을 수행 할 수 자바에 관한 것이 아니라 쉘에 관한 것입니다. 내가 아는 한, 쉘 인터프리터는 zip 파일에있는 스크립트를 실행할 수 없다. 따라서 여기에 몇 가지 옵션이 있습니다 :

  1. Java 프로그램 내에서 셸 스크립트를 텍스트 파일로 읽습니다. 임시 디렉토리에 임시 파일 (또는 기타 관련 장소를 생성하고이 파일의 내용을 복사합니다. 그리고이 시간 스크립트 쉘 인터프리터를 호출합니다. 을 저는 믿습니다 그 가장 좋은 방법

  2. 을 항아리가 있기 때문에 zip을 사용하는 경우 쉘에서 압축을 풀고 스크립트를 찾아 쉘을 실행할 수 있습니다.다시 이것은 어색하고 오히려 잘못이지만 기술적으로는 효과가 있습니다.

  3. 스크립트에 저수준 항목이없는 경우 논리를 Groovy 스크립트로 다시 작성하는 것을 고려해 볼 수 있습니다 (유용한 groosh 프로젝트를 찾을 수 있습니다). 그런 다음 파일에서가 아닌 메모리에서 groovy 코드를 호출하십시오. 내가 당신이라면

글쎄, 난 아이디어 나갈거야, 나는 ... 최초의 솔루션 : 행운을 구현하고 이것이 내가 대개 할

+0

답변을 주셔서 감사합니다. jar 파일에서 임시 위치로 셸 스크립트를 추출한 다음 거기에서 추출하는 방법을 알 수 있습니다. 어떻게 할 수 있는지 알고 있습니까? 이것을하거나 링크를 알고 있습니까? 귀하의 답변 주셔서 감사합니다! – Cristian

+0

다른 곳에서 언급했듯이 다음을 할 수 있습니다. unzip -p JARFILE SCRIPTFILE | 세게 때리다. 이것은 기본적으로 jar 파일을 추출하지만 실제로 파일을 생성하지는 않습니다. – Jay

3

가장 간단한 해결책은 응용 프로그램에서 쉘 스크립트를 임시 위치에 추출하여 거기에서 실행시키는 것입니다.

File.createTempFile(String, String)을 호출하여 Java로 임시 파일을 생성 할 수 있습니다.

또 다른 일은 쉘의 표준 입력과 같이 jar에서로드 된 스크립트의 내용을 전달하는 것입니다. 내가 스크립트 a.sh을 포함하는 아카이브 a.zip이 있다면 단순화로

,이 그것을 실행하는 것입니다 :

import java.io.*; 
class Test{ 

    public static void main(String[]args) throws Exception { 

    StringBuilder sb = new StringBuilder(); 

    // You're not strictly speaking executing a shell script but 
    // rather programatically typing commands into the shell 
    // sb.append("#!/bin/bash\n"); 
    sb.append("echo Hello world!\n"); 
    sb.append("cd /tmp\n"); 
    sb.append("echo current directory: `pwd`\n"); 

    // Start the shell 
    ProcessBuilder pb = new ProcessBuilder("/bin/bash"); 
    Process bash = pb.start(); 

    // Pass commands to the shell 
    PrintStream ps = new PrintStream(bash.getOutputStream()); 
    ps.println(sb); 
    ps.close(); 

    // Get an InputStream for the stdout of the shell 
    BufferedReader br = new BufferedReader(
     new InputStreamReader(bash.getInputStream())); 

    // Retrieve and print output 
    String line; 
    while (null != (line = br.readLine())) { 
     System.out.println("> "+line); 
    } 
    br.close(); 

    // Make sure the shell has terminated, print out exit value 
    System.out.println("Exit code: " + bash.waitFor()); 

    } 

} 
+0

사용자의 시스템에 파일을 복사하지 않아도되고 싶습니다. 프로그램에서 사용되는 스크립트의 내용을 어떻게 전달합니까? – Cristian

+0

내 의견으로는 매우 흥미로운 솔루션, 공유 주셔서 감사합니다. –

0

도움이되기를 바랍니다 것

$ jar xf myapp.jar run.sh && ./run.sh && rm run.sh 

... 필요한 경우 Runtime.exec()에서 호출 할 수 있습니다.

+0

그 jar 파일이 커맨드 라인에서 실행되었지만 실행 가능한 jar 파일 인 경우 좋을 것입니다. – Cristian

+0

Runtime.exec()를 통해 실행하면 해당 파일을 감당할 수 있어야합니다. – rich

관련 문제