Java 코드에서 Unix 쉘 스크립트를 실행하는 방법은 무엇입니까?
Java에서 Unix 명령을 실행하는 것은 매우 간단합니다.
Runtime.getRuntime().exec(myCommand);
그러나 Java 코드에서 Unix 쉘 스크립트를 실행할 수 있습니까? 그렇다면 Java 코드 내에서 쉘 스크립트를 실행하는 것이 좋습니다.
실제로 Process Builder를 살펴보십시오 . 실제로 이런 종류의 것을 위해 만들어졌습니다.
ProcessBuilder pb = new ProcessBuilder("myshellScript.sh", "myArg1", "myArg2");
Map<String, String> env = pb.environment();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
pb.directory(new File("myDir"));
Process p = pb.start();
Java 에서 쉘 스크립트를 실행하는 것이 Java의 정신에 있지 않다고 말하고 싶습니다 . Java는 크로스 플랫폼이어야하며 쉘 스크립트를 실행하면 사용이 UNIX로만 제한됩니다.
그렇게 말하면 Java 내에서 쉘 스크립트를 실행할 수 있습니다. 나열된 구문과 정확히 동일한 구문을 사용합니다 (내가 직접 시도하지는 않았지만 쉘 스크립트를 직접 실행 해보십시오. 그래도 작동하지 않으면 쉘 자체를 실행하고 스크립트를 명령 행 매개 변수로 전달하십시오) .
나는 당신이 자신의 질문에 대답했다고 생각합니다.
Runtime.getRuntime().exec(myShellScript);
좋은 습관인지에 관해서는 Java로 할 수없는 쉘 스크립트로 무엇을하려고합니까?
Apache Commons exec 라이브러리 도 사용할 수 있습니다 .
예 :
package testShellScript;
import java.io.IOException;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
public class TestScript {
int iExitValue;
String sCommandString;
public void runScript(String command){
sCommandString = command;
CommandLine oCmdLine = CommandLine.parse(sCommandString);
DefaultExecutor oDefaultExecutor = new DefaultExecutor();
oDefaultExecutor.setExitValue(0);
try {
iExitValue = oDefaultExecutor.execute(oCmdLine);
} catch (ExecuteException e) {
System.err.println("Execution failed.");
e.printStackTrace();
} catch (IOException e) {
System.err.println("permission denied.");
e.printStackTrace();
}
}
public static void main(String args[]){
TestScript testScript = new TestScript();
testScript.runScript("sh /root/Desktop/testScript.sh");
}
}
추가 참조를 위해 Apache Doc 에서도 예제를 제공합니다 .
그렇습니다. 이것은 나를 위해 일했다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.omg.CORBA.portable.InputStream;
public static void readBashScript() {
try {
Process proc = Runtime.getRuntime().exec("/home/destino/workspace/JavaProject/listing.sh /"); //Whatever you want to execute
BufferedReader read = new BufferedReader(new InputStreamReader(
proc.getInputStream()));
try {
proc.waitFor();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
while (read.ready()) {
System.out.println(read.readLine());
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
여기 내 예가 있습니다. 이해하기를 바랍니다.
public static void excuteCommand(String filePath) throws IOException{
File file = new File(filePath);
if(!file.isFile()){
throw new IllegalArgumentException("The file " + filePath + " does not exist");
}
if(this.isLinux()){
Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", filePath}, null);
}else if(this.isWindows()){
Runtime.getRuntime().exec("cmd /c start " + filePath);
}
}
public static boolean isLinux(){
String os = System.getProperty("os.name");
return os.toLowerCase().indexOf("linux") >= 0;
}
public static boolean isWindows(){
String os = System.getProperty("os.name");
return os.toLowerCase().indexOf("windows") >= 0;
}
절대 경로를 하드 코딩하지 않으려면 루트 디렉토리에있는 스크립트를 찾아서 실행하는 다음 방법을 사용할 수 있습니다.
public static void runScript() throws IOException, InterruptedException {
ProcessBuilder processBuilder = new ProcessBuilder("./nameOfScript.sh");
//Sets the source and destination for subprocess standard I/O to be the same as those of the current Java process.
processBuilder.inheritIO();
Process process = processBuilder.start();
int exitValue = process.waitFor();
if (exitValue != 0) {
// check for errors
new BufferedInputStream(process.getErrorStream());
throw new RuntimeException("execution of script failed!");
}
}
그렇습니다, 가능하고 당신은 그것에 응답했습니다! 좋은 연습에 대해서는 파일에서 직접 명령을 실행하지 말고 파일에서 명령을 실행하는 것이 좋습니다. 따라서 Java가 기존 .bat, .sh, .ksh ... 파일에서 명령 목록 (또는 하나의 명령)을 실행하도록해야합니다. 다음은 "MyFile.sh"파일에서 명령 목록을 실행하는 예입니다.
String[] cmd = { "sh", "MyFile.sh", "\pathOfTheFile"};
Runtime.getRuntime().exec(cmd);
ZT 프로세스 실행자 라이브러리는 아파치 코 몬즈 Exec에서의 대안입니다. 명령 실행, 출력 캡처, 시간 초과 설정 등의 기능이 있습니다.
아직 사용하지는 않았지만 합리적으로 잘 정리되어 있습니다.
문서의 예 : 명령 실행, stderr를 로거로 펌핑하여 UTF8 문자열로 출력을 리턴합니다.
String output = new ProcessExecutor().command("java", "-version")
.redirectError(Slf4jStream.of(getClass()).asInfo())
.readOutput(true).execute()
.outputUTF8();
이 문서에는 Commons Exec에 비해 다음과 같은 장점이 있습니다.
- 스트림 처리 개선
- 스트림 읽기 / 쓰기
- stderr를 stdout으로 리디렉션
- 타임 아웃 처리 개선
- 종료 코드 점검 개선
- 개선 된 API
- 매우 복잡한 사용 사례를위한 하나의 라이너
- 프로세스 출력을 문자열로 얻는 하나의 라이너
- 사용 가능한 프로세스 개체에 액세스
- 비동기 프로세스 지원 ( Future )
- SLF4J API를 통한 로깅 향상
- 여러 프로세스 지원
나에 관해서는 모든 것이 간단해야합니다. 스크립트를 실행하려면 실행해야합니다.
new ProcessBuilder("pathToYourShellScript").start();
다음은 Java에서 Unix bash 또는 Windows bat / cmd 스크립트를 실행하는 방법의 예입니다. 스크립트에서 인수를 전달하고 스크립트에서 출력을 수신 할 수 있습니다. 이 메소드는 임의의 수의 인수를 허용합니다.
public static void runScript(String path, String... args) {
try {
String[] cmd = new String[args.length + 1];
cmd[0] = path;
int count = 0;
for (String s : args) {
cmd[++count] = args[count - 1];
}
Process process = Runtime.getRuntime().exec(cmd);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
try {
process.waitFor();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
while (bufferedReader.ready()) {
System.out.println("Received from script: " + bufferedReader.readLine());
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
System.exit(1);
}
}
유닉스 / 리눅스에서 실행할 때 경로는 유닉스와 같아야하며 ( '/'를 구분 기호로 사용) Windows에서 실행할 때는 '\'를 사용하십시오. Hier는 임의의 수의 인수를 받고 모든 인수를 두 배로 만드는 bash 스크립트 (test.sh)의 예입니다.
#!/bin/bash
counter=0
while [ $# -gt 0 ]
do
echo argument $((counter +=1)): $1
echo doubling argument $((counter)): $(($1+$1))
shift
done
전화 할 때
runScript("path_to_script/test.sh", "1", "2")
유닉스 / 리눅스에서 출력은 다음과 같습니다.
Received from script: argument 1: 1
Received from script: doubling argument 1: 2
Received from script: argument 2: 2
Received from script: doubling argument 2: 4
Hier는 간단한 cmd Windows 스크립트 test.cmd로 여러 입력 인수를 계산합니다.
@echo off
set a=0
for %%x in (%*) do Set /A a+=1
echo %a% arguments received
Windows에서 스크립트를 호출 할 때
runScript("path_to_script\\test.cmd", "1", "2", "3")
출력은
Received from script: 3 arguments received
다른 프로그램처럼 실행할 수도 있습니다. 스크립트에 적절한 #이 있는지 확인하십시오! (she-bang) 행을 스크립트의 첫 번째 행으로 사용하고 파일에 대한 실행 권한이 있는지 확인하십시오.
예를 들어, bash 스크립트 인 경우 #! / bin / bash를 스크립트의 맨 위에 두십시오. 또한 chmod + x입니다.
또한 좋은 습관 인 경우, 특히 Java의 경우는 아니지만 큰 스크립트를 이식하는 데 많은 시간을 절약하고 추가 비용을 지불하지 않으면 시간을 절약하십시오.) 스크립트를 작성하고 장기적인 할 일 목록에 Java로 포팅하십시오.
String scriptName = PATH+"/myScript.sh";
String commands[] = new String[]{scriptName,"myArg1", "myArg2"};
Runtime rt = Runtime.getRuntime();
Process process = null;
try{
process = rt.exec(commands);
process.waitFor();
}catch(Exception e){
e.printStackTrace();
}
이것은 늦은 답변입니다. 그러나 미래 개발자를 위해 Spring-Boot 응용 프로그램에서 쉘 스크립트를 실행하려면 많은 노력을 기울여야한다고 생각했습니다.
나는 Spring-Boot에서 일하고 있었고 Java 응용 프로그램에서 실행할 파일을 찾을 수 없어서 던졌습니다
FileNotFoundFoundException
. 파일을resources
디렉토리 에 보관하고pom.xml
응용 프로그램이 다음과 같이 시작되는 동안 파일을 검색하도록 설정해야 했습니다.<resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*.xml</include> <include>**/*.properties</include> <include>**/*.sh</include> </includes> </resource> </resources>
- 그 후 파일을 실행하는 데 문제가 있었고을 반환했습니다
error code = 13, Permission Denied
. 그런 다음이 명령을 실행하여 파일을 실행 가능하게 만들어야했습니다.chmod u+x myShellScript.sh
마지막으로 다음 코드 스 니펫을 사용하여 파일을 실행할 수 있습니다.
public void runScript() {
ProcessBuilder pb = new ProcessBuilder("src/main/resources/myFile.sh");
try {
Process p;
p = pb.start();
} catch (IOException e) {
e.printStackTrace();
}
}
누군가의 문제를 해결하기를 바랍니다.
솔라리스 5.10과 똑같이 작동 ./batchstart.sh
하는 것은 OS가 그것을 \\. batchstart.sh
대신 사용하는지 알지 못하는 트릭 이 있습니다 . 이 이중 슬래시가 도움이 될 수 있습니다.
나는 생각한다
System.getProperty("os.name");
운영 체제를 점검하면 쉘 / bash 스크립이 지원되는 경우이를 관리 할 수 있습니다. 코드를 이식 가능하게 만들어야하는 경우.
리눅스 용
public static void runShell(String directory, String command, String[] args, Map<String, String> environment)
{
try
{
if(directory.trim().equals(""))
directory = "/";
String[] cmd = new String[args.length + 1];
cmd[0] = command;
int count = 1;
for(String s : args)
{
cmd[count] = s;
count++;
}
ProcessBuilder pb = new ProcessBuilder(cmd);
Map<String, String> env = pb.environment();
for(String s : environment.keySet())
env.put(s, environment.get(s));
pb.directory(new File(directory));
Process process = pb.start();
BufferedReader inputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedWriter outputReader = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
int exitValue = process.waitFor();
if(exitValue != 0) // has errors
{
while(errReader.ready())
{
LogClass.log("ErrShell: " + errReader.readLine(), LogClass.LogMode.LogAll);
}
}
else
{
while(inputReader.ready())
{
LogClass.log("Shell Result : " + inputReader.readLine(), LogClass.LogMode.LogAll);
}
}
}
catch(Exception e)
{
LogClass.log("Err: RunShell, " + e.toString(), LogClass.LogMode.LogAll);
}
}
public static void runShell(String path, String command, String[] args)
{
try
{
String[] cmd = new String[args.length + 1];
if(!path.trim().isEmpty())
cmd[0] = path + "/" + command;
else
cmd[0] = command;
int count = 1;
for(String s : args)
{
cmd[count] = s;
count++;
}
Process process = Runtime.getRuntime().exec(cmd);
BufferedReader inputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedWriter outputReader = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
int exitValue = process.waitFor();
if(exitValue != 0) // has errors
{
while(errReader.ready())
{
LogClass.log("ErrShell: " + errReader.readLine(), LogClass.LogMode.LogAll);
}
}
else
{
while(inputReader.ready())
{
LogClass.log("Shell Result: " + inputReader.readLine(), LogClass.LogMode.LogAll);
}
}
}
catch(Exception e)
{
LogClass.log("Err: RunShell, " + e.toString(), LogClass.LogMode.LogAll);
}
}
그리고 사용을 위해;
ShellAssistance.runShell("", "pg_dump", new String[]{"-U", "aliAdmin", "-f", "/home/Backup.sql", "StoresAssistanceDB"});
또는
ShellAssistance.runShell("", "pg_dump", new String[]{"-U", "aliAdmin", "-f", "/home/Backup.sql", "StoresAssistanceDB"}, new Hashmap<>());
참고 URL : https://stackoverflow.com/questions/525212/how-to-run-unix-shell-script-from-java-code
'IT story' 카테고리의 다른 글
SQL : 열에서 각 고유 값의 개수를 얻는 방법은 무엇입니까? (0) | 2020.06.13 |
---|---|
github에서 repo의 이름이 바뀌는 오류가 발생했습니다.“원격 :이 저장소가 이동했습니다. (0) | 2020.06.13 |
예기치 않은 토큰 내보내기 (0) | 2020.06.13 |
Java에서 시스템 변수 값을 얻으려면 어떻게해야합니까? (0) | 2020.06.13 |
YouTube 동영상의 종료 시간을 맞춤 설정하는 방법 (0) | 2020.06.13 |