जावा से यूनिक्स कमांड चलाना काफी सरल है।
Runtime.getRuntime().exec(myCommand);
लेकिन क्या जावा कोड से यूनिक्स शेल स्क्रिप्ट चलाना संभव है? यदि हाँ, तो क्या जावा कोड के भीतर से शेल स्क्रिप्ट चलाना एक अच्छा अभ्यास होगा?
जावा से यूनिक्स कमांड चलाना काफी सरल है।
Runtime.getRuntime().exec(myCommand);
लेकिन क्या जावा कोड से यूनिक्स शेल स्क्रिप्ट चलाना संभव है? यदि हाँ, तो क्या जावा कोड के भीतर से शेल स्क्रिप्ट चलाना एक अच्छा अभ्यास होगा?
जवाबों:
आपको वास्तव में प्रोसेस बिल्डर को देखना चाहिए । यह वास्तव में इस तरह की चीज के लिए बनाया गया है।
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();
आप अपाचे कॉमन्स निष्पादन पुस्तकालय का भी उपयोग कर सकते हैं ।
उदाहरण :
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 पर भी एक उदाहरण दिया गया है ।
OutputStream
लिए सेट कर सकते हैं । कृपया इस धागे को अधिक जानकारी के लिए देखें: मैं एक कमांड के आउटपुट को कैसे पकड़ सकता हूं ...DefaultExecuter
DefaultExecuter.setStreamHandler
OutputStream
मैं कहूंगा कि जावा से शेल स्क्रिप्ट चलाना जावा की भावना में नहीं है । जावा का मतलब क्रॉस प्लेटफॉर्म है, और एक शेल स्क्रिप्ट को चलाने से इसका उपयोग सिर्फ यूनिक्स तक सीमित हो जाएगा।
उस के साथ, यह निश्चित रूप से जावा के भीतर से एक खोल स्क्रिप्ट चलाने के लिए संभव है। आप अपने द्वारा सूचीबद्ध समान सिंटैक्स का उपयोग करेंगे (मैंने इसे स्वयं आज़माया नहीं है, लेकिन शेल स्क्रिप्ट को सीधे निष्पादित करने का प्रयास करें, और यदि वह काम नहीं करता है, तो शेल को निष्पादित करें, कमांड लाइन पैरामीटर के रूप में स्क्रिप्ट को पास करना) ।
switches
और if
बयानों को लिखते हैं जो जावा कोर पुस्तकालयों के साथ आए लोगों के सर्वोत्तम प्रयासों के बावजूद विभिन्न प्लेटफार्मों पर बिल्कुल समान नहीं हैं।
मुझे लगता है कि आपने अपने प्रश्न का उत्तर दिया है
Runtime.getRuntime().exec(myShellScript);
जैसे कि यह अच्छा अभ्यास है ... आप एक शेल स्क्रिप्ट के साथ क्या करने की कोशिश कर रहे हैं जो आप जावा के साथ नहीं कर सकते हैं?
हां ऐसा करना संभव है। इसने मेरे लिए काम किया।
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;
}
हाँ, यह संभव है और आपने इसका उत्तर दिया है! अच्छी प्रथाओं के बारे में, मुझे लगता है कि फ़ाइलों से कमांड लॉन्च करना बेहतर है और सीधे आपके कोड से नहीं। आप बनाना है तो जावा में एक मौजूदा आदेश (या एक आदेश) की सूची पर अमल .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 कॉमन्स Exec के लिए एक विकल्प है। इसमें कमांड चलाने, उनके आउटपुट को कैप्चर करने, टाइमआउट सेट करने आदि की कार्यक्षमता है।
मैंने अभी तक इसका उपयोग नहीं किया है, लेकिन यह काफी अच्छी तरह से प्रलेखित है।
प्रलेखन से एक उदाहरण: कमांड को निष्पादित करना, एक लकड़हारे को stderr पंप करना, आउटपुट को UTF8 स्ट्रिंग के रूप में वापस करना।
String output = new ProcessExecutor().command("java", "-version")
.redirectError(Slf4jStream.of(getClass()).asInfo())
.readOutput(true).execute()
.outputUTF8();
इसका प्रलेखन कॉमन्स एक्सक पर निम्नलिखित लाभों को सूचीबद्ध करता है:
यहां एक उदाहरण है कि जावा से यूनिक्स बैश या विंडोज बैट / सेमी स्क्रिप्ट कैसे चलाया जाए। स्क्रिप्ट से प्राप्त स्क्रिप्ट और आउटपुट पर तर्क पारित किए जा सकते हैं। विधि मनमानी संख्या तर्कों को स्वीकार करती है।
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);
}
}
जब यूनिक्स / लिनक्स पर चल रहा हो, तो पथ को यूनिक्स की तरह ('/' सेपरेटर के रूप में) होना चाहिए, जब विंडोज पर चल रहा हो - '\' का उपयोग करें। हायर एक बैश स्क्रिप्ट (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 विंडोज स्क्रिप्ट test.cmd है जो इनपुट तर्कों की संख्या की गणना करता है:
@echo off
set a=0
for %%x in (%*) do Set /A a+=1
echo %a% arguments received
विंडोज पर स्क्रिप्ट को कॉल करते समय
runScript("path_to_script\\test.cmd", "1", "2", "3")
आउटपुट है
Received from script: 3 arguments received
यह संभव है, बस इसे किसी अन्य कार्यक्रम के रूप में निष्पादित करें। बस सुनिश्चित करें कि आपकी स्क्रिप्ट में उचित # है! (she-bang) लाइन स्क्रिप्ट की पहली लाइन के रूप में है, और सुनिश्चित करें कि फ़ाइल पर अनुमतियाँ निष्पादित हैं।
उदाहरण के लिए, यदि यह स्क्रिप्ट के शीर्ष पर एक बैश स्क्रिप्ट है #! / बिन / बैश, भी chmod + x।
इसके अलावा जैसे कि यह अच्छा अभ्यास है, नहीं, यह विशेष रूप से जावा के लिए नहीं है, लेकिन अगर यह आपको एक बड़ी स्क्रिप्ट को पोर्ट करने में बहुत समय बचाता है, और आपको इसे करने के लिए अतिरिक्त भुगतान नहीं किया जा रहा है;) अपना समय बचाएं, निष्पादित करें स्क्रिप्ट, और पोर्टिंग को जावा को अपनी लंबी अवधि की टूडू सूची में डालें।
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();
}
यह एक देर से जवाब है। हालाँकि, मैंने सोचा था कि भविष्य के डेवलपर्स के लिए स्प्रिंग-बूट एप्लिकेशन से निष्पादित होने के लिए मुझे एक शेल स्क्रिप्ट प्राप्त करने के लिए संघर्ष करना होगा।
मैं स्प्रिंग-बूट में काम कर रहा था और मुझे अपने जावा एप्लिकेशन से निष्पादित होने वाली फ़ाइल नहीं मिल रही थी और यह फेंक रहा था 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();
}
}
आशा है कि किसी की समस्या को हल करता है।
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<>());