জাভা থেকে ইউনিক্স কমান্ড চালানো বেশ সহজ।
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");
}
}
আরও রেফারেন্সের জন্য, অ্যাপাচি ডকেও একটি উদাহরণ দেওয়া আছে ।
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 প্রক্রিয়া নির্বাহক গ্রন্থাগার এ্যাপাচি কমন্স Exec এর একটি বিকল্প। কমান্ড চালানো, আউটপুট ক্যাপচার করা, টাইমআউট সেট করা ইত্যাদির কার্যকারিতা রয়েছে It
আমি এখনও এটি ব্যবহার করি নি, তবে এটি যুক্তিসঙ্গতভাবে ভাল-ডকুমেন্টেড দেখায়।
ডকুমেন্টেশন থেকে একটি উদাহরণ: একটি কমান্ড কার্যকর করা, স্টার্ডারকে একটি লগারে পাম্প করা, আউটপুটটিকে ইউটিএফ 8 স্ট্রিং হিসাবে ফিরিয়ে দেওয়া।
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);
}
}
ইউনিক্স / লিনাক্সে চলাকালীন, উইন্ডোজ চলাকালীন, पथটি অবশ্যই ইউনিক্সের মতো ('/' বিভাজক হিসাবে) থাকতে হবে - '\' ব্যবহার করুন। হাইয়ার বাশ স্ক্রিপ্টের একটি উদাহরণ (টেস্ট.শ) যা নির্বিচারে সংখ্যক আর্গুমেন্ট গ্রহণ করে এবং প্রতিটি যুক্তি দ্বিগুণ করে:
#!/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
হাইয়ার হ'ল একটি সাধারণ সেন্টিমিডি উইন্ডোজ স্ক্রিপ্ট টেস্ট.কম, যা ইনপুট আর্গুমেন্টগুলির সংখ্যা গণনা করে:
@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
এটি সম্ভব, কেবল এটি অন্য প্রোগ্রাম হিসাবে চালিত করুন। আপনার স্ক্রিপ্টের যথাযথ # আছে তা নিশ্চিত করুন! স্ক্রিপ্টের প্রথম লাইন হিসাবে (সে-ব্যাং) লাইন এবং ফাইলটিতে অনুমতি সম্পাদনের অনুমতি রয়েছে কিনা তা নিশ্চিত করুন।
উদাহরণস্বরূপ, যদি এটি কোনও বাশ স্ক্রিপ্ট হয় তবে স্ক্রিপ্টের শীর্ষে #! / বিন / বাশ লাগান, 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();
}
এটি একটি দেরী উত্তর। যাইহোক, আমি ভবিষ্যতের বিকাশকারীদের জন্য একটি স্প্রিং-বুট অ্যাপ্লিকেশন থেকে শেল স্ক্রিপ্ট কার্যকর করার জন্য আমার যে সংগ্রামটি সহ্য করতে হয়েছিল তা ভেবে ভেবেছিলাম putting
আমি স্প্রিং-বুটে কাজ করছিলাম এবং আমি আমার জাভা অ্যাপ্লিকেশন থেকে চালানো ফাইলটি খুঁজে পাইনি এবং এটি নিক্ষেপ করছে 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();
}
}
আশা করি যে কারও সমস্যা সমাধান করবে।
লিনাক্স ব্যবহারের জন্য
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<>());