Java 코드에서 Unix 쉘 스크립트를 실행하는 방법
Java에서 Unix 명령을 실행하는 것은 매우 간단합니다.
Runtime.getRuntime().exec(myCommand);
그러나 Java 코드에서 Unix 쉘 스크립트를 실행할 수 있습니까?그렇다면 Java 코드 내에서 셸 스크립트를 실행하는 것이 좋을까요?
프로세스 빌더를 살펴봐야 합니다.이건 정말 이런 종류의 것을 위해 만들어졌습니다.
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();
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에도 예가 나와 있습니다.
제 생각에 당신은 당신 자신의 질문에 답한 것 같습니다.
Runtime.getRuntime().exec(myShellScript);
그것이 좋은 관행인지 아닌지에 대해서…자바에서는 할 수 없는 셸 스크립트로 무엇을 하려고 합니까?
자바에서 셸 스크립트를 실행하는 것은 자바 정신에 맞지 않는다고 생각합니다.Java는 크로스 플랫폼이어야 하며 셸 스크립트를 실행하면 UNIX로만 사용이 제한됩니다.
이와 같이 Java 내에서 셸 스크립트를 실행하는 것은 확실히 가능합니다.목록과 동일한 구문을 사용합니다(제가 직접 사용해 본 적은 없지만 셸 스크립트를 직접 실행해보고, 그래도 작동하지 않으면 셸 자체를 실행하여 스크립트를 명령줄 파라미터로 전달합니다).
네, 그렇게 하는 것은 가능합니다.나한테는 잘된 일이야.
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(isLinux()){
Runtime.getRuntime().exec(new String[] {"/bin/sh", "-c", filePath}, null);
}else if(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;
}
합니다. 대답하다.은 코드에서 직접 를 실행하는 것이 아니라 파일에서 명령을 실행하는합니다.모범 사례에 대해서는 코드에서 직접 명령어를 실행하는 것이 아니라 파일에서 명령어를 실행하는 것이 좋다고 생각합니다. 기존 "Java"에 명령어 의 명령어..bat
,.sh
,.ksh
...파일 에 제시하겠습니다.MyFile.sh
:
String[] cmd = { "sh", "MyFile.sh", "\pathOfTheFile"};
Runtime.getRuntime().exec(cmd);
절대 경로를 하드코드할 필요가 없도록 다음 방법을 사용하여 스크립트가 루트 디렉토리에 있는 경우 스크립트를 검색하여 실행할 수 있습니다.
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!");
}
}
나로서는 모든 것이 간단해야 한다.스크립트를 실행하려면 실행만 하면 됩니다.
new ProcessBuilder("pathToYourShellScript").start();
ZT 프로세스 실행 프로그램 라이브러리는 Apache Commons Exec 대신 사용할 수 있습니다.명령어 실행, 출력 캡처, 타임아웃 설정 등이 가능합니다.
아직 써본 적은 없지만, 상당히 문서화되어 있는 것 같습니다.
문서의 예를 다음에 나타냅니다.명령어를 실행하여 stderr을 로거에 펌핑하고 출력을 UTF8 문자열로 반환합니다.
String output = new ProcessExecutor().command("java", "-version")
.redirectError(Slf4jStream.of(getClass()).asInfo())
.readOutput(true).execute()
.outputUTF8();
이 문서에는 Commons Exec에 비해 다음과 같은 이점이 있습니다.
- 스트림 처리 개선
- 스트림 읽기/쓰기
- stderr을 stdout으로 리다이렉트하는 중
- 타임아웃 처리 개선
- 종료 코드 확인 기능 향상
- 【 】API
- 매우 복잡한 사용 사례를 위한 하나의 라이너
- 프로세스 출력을 문자열로 가져오기 위한 라이너 1개
- Process 객체에 액세스할 수 있습니다.
- 비동기 프로세스 지원(Future
- SLF4J API를 통한 로깅 향상
- 여러 프로세스 지원
다음으로 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);
}
}
Unix/Linux에서 실행할 경우 경로는 Unix와 같아야 합니다(Windows에서 실행할 경우 '\'를 사용하십시오).Hier는 임의의 수의 인수를 수신하여 모든 인수를 2배로 하는 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")
Unix/Linux 의 출력은 다음과 같습니다.
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
이것은 답장이 늦다.그러나 향후 개발자를 위해 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();
}
}
그게 누군가의 문제를 해결해 주길 바라.
가능합니다. 그냥 다른 프로그램과 같이 실행하세요.스크립트의 첫 번째 줄에 적절한 #!(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();
}
Solaris 5.10과 마찬가지로 다음과 같이 동작합니다../batchstart.sh
OS가 그 사용을 받아들일지 어떨지 모르는 트릭이 있습니다.\\. batchstart.sh
대신.이 더블 슬래시가 도움이 될 거야
제 생각에는
System.getProperty("os.name");
에서 운영체제를 체크하면 셸/배시 스크리프가 지원되는 경우 관리할 수 있습니다.코드를 휴대할 필요가 있는 경우.
Linux 용
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
'programing' 카테고리의 다른 글
Java Enum 정의 (0) | 2022.08.03 |
---|---|
코드의 maven pom.xml에서 버전을 가져옵니다. (0) | 2022.08.03 |
VueJS 디스패치 기능의 실행 순서에서 문제가 발생하고 있습니다. (0) | 2022.08.03 |
모달 vue에서 윈도우 프린트를 사용하려면 어떻게 해야 하나요? (0) | 2022.08.03 |
Java에서 시간 없이 데이트하려면 어떻게 해야 하나요? (0) | 2022.08.03 |