জাভা রানটাইম.সেটআরটাইম (): একটি কমান্ড লাইন প্রোগ্রাম কার্যকর করে আউটপুট পাচ্ছে


155

আমি আমার জাভা প্রোগ্রাম থেকে কমান্ড প্রম্পট কমান্ডগুলি চালানোর জন্য রানটাইম ব্যবহার করছি। তবে, আমি কীভাবে কমান্ডটি আউটপুট পেতে পারি তা সম্পর্কে আমি অবগত নই।

আমার কোডটি এখানে:

Runtime rt = Runtime.getRuntime();

String[] commands = {"system.exe", "-send" , argument};

Process proc = rt.exec(commands);

আমি চেষ্টা করেছিলাম System.out.println(proc);কিন্তু কিছুই ফিরে আসেনি। এই কমান্ডটি কার্যকর করার জন্য একটি সেমিকোলন দ্বারা পৃথক দুটি সংখ্যা ফিরে পাওয়া উচিত। আমি কীভাবে এটি মুদ্রণের জন্য একটি ভেরিয়েবলের মধ্যে পেতে পারি?

আমি এখন যে কোডটি ব্যবহার করছি তা এখানে:

String[] commands = {"system.exe", "-get t"};

Process proc = rt.exec(commands);

InputStream stdIn = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdIn);
BufferedReader br = new BufferedReader(isr);

String line = null;
System.out.println("<OUTPUT>");

while ((line = br.readLine()) != null)
     System.out.println(line);

System.out.println("</OUTPUT>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);

তবে আমি আমার আউটপুট হিসাবে কিছুই পাচ্ছি না, তবে আমি যখন নিজেরাই সেই আদেশটি চালাচ্ছি এটি ঠিকঠাক কাজ করে।

উত্তর:


244

এখানে যাওয়ার উপায়:

Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);

BufferedReader stdInput = new BufferedReader(new 
     InputStreamReader(proc.getInputStream()));

BufferedReader stdError = new BufferedReader(new 
     InputStreamReader(proc.getErrorStream()));

// Read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
    System.out.println(s);
}

// Read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
    System.out.println(s);
}

আরো বিস্তারিত জানার জন্য Javadoc পড়ুন এখানেProcessBuilderব্যবহার করার জন্য একটি ভাল পছন্দ হবে।


4
@ অ্যালবার্টচেন pwd && lsকেবল একটি একক ফাইল চালাচ্ছেন না, যখন আপনি শেলের মধ্যে এটি করেন এটি কার্যকর /bin/pwdএবং /bin/lsএক্সিকিউটেবল উভয়ই কার্যকর করে । আপনি যদি জাভাতে এর মতো জিনিসগুলি করতে চান তবে আপনার মতো কিছু করতে হবে {"/bin/bash","-c", "pwd && ls"}। আপনার কাছে সম্ভবত আর প্রশ্নটি নেই তবে অন্যান্য লোকেরা সম্ভবত আমার ভেবেছিল আমি এর উত্তর দিতে পারি।
735 টেসলা

3
আমি মনে করি দুটি স্ট্রিম অবশ্যই একই সাথে হওয়া উচিত কারণ আপনার মত যদি স্টাড স্ট্রিমের আউটপুট বাফারটি পূরণ করে তবে আপনি ত্রুটি প্রবাহটি পড়তে সক্ষম হবেন না ..
Li3ro

3
Li3ro আংশিকভাবে সঠিক। আপনি যে প্রোগ্রামটি শুনছেন তার একটি সীমিত বাফার stdoutএবং stderrআউটপুট রয়েছে। আপনি যদি তাদের একসাথে শুনতে না পান তবে আপনি অন্যটি পড়ার সময় তাদের একটি পূরণ করবে। প্রোগ্রাম আপনি শুনছেন তারপর ভরা বাফার লিখতে যখন অন্যান্য প্রান্তে আপনার প্রোগ্রাম একটি বাফার যে আর ফেরত আসবে না থেকে পড়ার চেষ্টা করার অবরুদ্ধ করবে চেষ্টা অবরুদ্ধ করবে EOF। আপনার অবশ্যই উভয় স্ট্রিম থেকে একই সাথে পড়তে হবে
গিলি

1
@ গিলি তাহলে Li3ro "আংশিক" ঠিক কেন? Li3ro ঠিক পুরোপুরি এবং সম্পূর্ণ সঠিক নয়? এই ক্ষেত্রে, আমি বুঝতে পারি না যে ২০১১ সাল থেকে এখানে কেন একটি ভুল উত্তর ঝুলছে এবং কেন এটির 200 টিরও বেশি উর্ধ্বে রয়েছে ... এটি বিভ্রান্তিকর।
আন্দ্রে টিউকিন

2
@ আন্ড্রেইটুকিন আপনি ঠিক বলেছেন সমস্ত বর্তমান উত্তরগুলি অচল অবস্থায় রয়েছে to আমি তাদের উত্সাহিত করি যাতে তারা অন্যান্য উত্তরগুলিকে দৃশ্যমানতা পেতে দেয়াকে কম করে দেয়। আমি আপনার পর্যালোচনার জন্য একটি নতুন উত্তর পোস্ট করেছি: stackoverflow.com/a/57949752/14731 । আশা করি আমি এই অধিকার পেয়েছি ...
গিলি

68

দ্রুততর উপায় হ'ল:

public static String execCmd(String cmd) throws java.io.IOException {
    java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

যা মূলত এটির একটি ঘন সংস্করণ:

public static String execCmd(String cmd) throws java.io.IOException {
    Process proc = Runtime.getRuntime().exec(cmd);
    java.io.InputStream is = proc.getInputStream();
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    String val = "";
    if (s.hasNext()) {
        val = s.next();
    }
    else {
        val = "";
    }
    return val;
}

আমি জানি এই প্রশ্নটি পুরানো তবে আমি এই উত্তরটি পোস্ট করছি কারণ আমি মনে করি এটি আরও দ্রুত হতে পারে।


4
সুন্দর উত্তরের জন্য ধন্যবাদ। কেন "\\ এ" সীমাবদ্ধ?
গটফ্রাইড

1
আমি মূলত এটি লেখার সময় আমার যুক্তিটি কী ছিল তা আমি পুরোপুরি মনে করতে পারি না। আমি এই সমাধানটি কিছুক্ষণ ব্যবহার করছি তবে আমি মনে করি এটি ছিল কারণ \Aএকটি রেইজেক্সের অর্থ স্ট্রিংয়ের শুরু এবং আমাকে স্ল্যাশ থেকে বাঁচতে হয়েছিল।
735 টেসলা

5
"\ এ" হল বেল চরিত্র। "^" হ'ল রেজিএক্সের একটি স্ট্রিংয়ের শুরু এবং "$" হ'ল রেজেক্সের একটি স্ট্রিংয়ের সমাপ্তি। এটি এমন একটি চরিত্র যা আপনি আশা করবেন না। জাভা ডকুমেন্টেশন অনুসারে ডিফল্ট ডিলিমিটারটি হোয়াইটস্পেস, তাই এটি করার ফলে সম্ভবত কমান্ডের পুরো ফলাফলটি ছিটকে যায়।
হ্যাঙ্ক শুল্টজ 12'15

11

ProcessBuilderপ্রস্তাবিত সেন্টথিল হিসাবে ব্যবহার করার পাশাপাশি , যখন রানটাইম.এক্সেক () না করবে তার সমস্ত প্রস্তাবনাগুলি পড়তে এবং প্রয়োগ করতে ভুলবেন না


এই স্নিপেট মানক ত্রুটি স্ট্রিম গ্রহণ করছে বলে মনে হচ্ছে না (লিঙ্কযুক্ত নিবন্ধে প্রস্তাবিত হিসাবে)। এটি ProcessBuilderএখন দুবার সুপারিশ করা হিসাবে ব্যবহার করে না । একটি ব্যবহার করে ProcessBuilder, একসাথে উভয় গ্রাহ্য করা সহজতর করার জন্য আউটপুট এবং ত্রুটি স্ট্রিমগুলি একত্রিত করা সম্ভব।
অ্যান্ড্রু থম্পসন

11

ক্লাসপথে যদি ইতিমধ্যে অ্যাপাচি কমন্স-আইও উপলব্ধ থাকে তবে আপনি ব্যবহার করতে পারেন:

Process p = new ProcessBuilder("cat", "/etc/something").start();
String stderr = IOUtils.toString(p.getErrorStream(), Charset.defaultCharset());
String stdout = IOUtils.toString(p.getInputStream(), Charset.defaultCharset());

7

এছাড়াও আমরা কমান্ড আউটপুট পেতে স্ট্রিম ব্যবহার করতে পারি:

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

        Runtime runtime = Runtime.getRuntime();
        String[] commands  = {"free", "-h"};
        Process process = runtime.exec(commands);

        BufferedReader lineReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        lineReader.lines().forEach(System.out::println);

        BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        errorReader.lines().forEach(System.out::println);
    }

7

@ সেন্থিল এবং @ আরেন্ড উত্তর ( https://stackoverflow.com/a/5711150/2268559 ) উল্লিখিত হয়েছে ProcessBuilderProcessBuilderকমান্ডের জন্য এনভায়রনমেন্ট ভেরিয়েবল এবং ওয়ার্কিং ফোল্ডার নির্দিষ্ট করে ব্যবহার করার উদাহরণ এখানে রয়েছে :

    ProcessBuilder pb = new ProcessBuilder("ls", "-a", "-l");

    Map<String, String> env = pb.environment();
    // If you want clean environment, call env.clear() first
    //env.clear();
    env.put("VAR1", "myValue");
    env.remove("OTHERVAR");
    env.put("VAR2", env.get("VAR1") + "suffix");

    File workingFolder = new File("/home/user");
    pb.directory(workingFolder);

    Process proc = pb.start();

    BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));

    BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

    // Read the output from the command:
    System.out.println("Here is the standard output of the command:\n");
    String s = null;
    while ((s = stdInput.readLine()) != null)
        System.out.println(s);

    // Read any errors from the attempted command:
    System.out.println("Here is the standard error of the command (if any):\n");
    while ((s = stdError.readLine()) != null)
        System.out.println(s);

6

এই লেখার সময়, কোড সহ অন্তর্ভুক্ত অন্যান্য সমস্ত উত্তরগুলির ফলাফল অচল অবস্থায় থাকতে পারে।

প্রক্রিয়াগুলির জন্য stdoutএবং stderrআউটপুট সীমিত বাফার থাকে । আপনি যদি তাদের সাথে একসাথে কথা না শোনেন, আপনি অন্যটি পড়ার চেষ্টা করার সময় তাদের মধ্যে একটি পূরণ করবে। উদাহরণস্বরূপ, stdoutপ্রক্রিয়াটি লেখার অপেক্ষায় আপনি পড়তে অপেক্ষা করতে পারেন stderr। আপনি stdoutবাফার থেকে পড়তে পারবেন না কারণ এটি খালি এবং প্রক্রিয়াটি stderrপূর্ণ হওয়ার কারণে বাফারে লিখতে পারে না । আপনি প্রত্যেকে চিরকাল একে অপরের জন্য অপেক্ষা করছেন।

ডেডলকসের ঝুঁকি ছাড়াই প্রক্রিয়াটির আউটপুট পড়ার সম্ভাব্য উপায় এখানে:

public final class Processes
{
    private static final String NEWLINE = System.getProperty("line.separator");

    /**
     * @param command the command to run
     * @return the output of the command
     * @throws IOException if an I/O error occurs
     */
    public static String run(String... command) throws IOException
    {
        ProcessBuilder pb = new ProcessBuilder(command).redirectErrorStream(true);
        Process process = pb.start();
        StringBuilder result = new StringBuilder(80);
        try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())))
        {
            while (true)
            {
                String line = in.readLine();
                if (line == null)
                    break;
                result.append(line).append(NEWLINE);
            }
        }
        return result.toString();
    }

    /**
     * Prevent construction.
     */
    private Processes()
    {
    }
}

কী ব্যবহার করা ProcessBuilder.redirectErrorStream(true)হয় যা পুনর্চালনা করবে stderrমধ্যে stdoutপ্রবাহ। এটি আপনাকে stdoutএবং এর মধ্যে বিকল্প না করে একটি একক স্ট্রিম পড়তে দেয় stderr। আপনি যদি ম্যানুয়ালি এটিকে প্রয়োগ করতে চান তবে আপনাকে কখনও ব্লক করা উচিত নয় তা নিশ্চিত করতে আপনাকে দুটি পৃথক থ্রেডে স্ট্রিম গ্রহণ করতে হবে।


কি শান্তি! আমি আশা করিনি যে আপনি এত তাড়াতাড়ি মন্তব্যে জবাব দেবেন, চিরকালীন এই পুরানো প্রশ্নের উত্তরটি ছেড়ে দিন! :) আমি এখন একটি অনুগ্রহ শুরু করার বিষয়ে বিবেচনা করছি। আপনার উত্তরটি পরে দেখুন। ধন্যবাদ!
আন্দ্রে টিউকিন

1

আপনি যদি কোটলিনে লিখেন তবে আপনি এটি ব্যবহার করতে পারেন:

val firstProcess = ProcessBuilder("echo","hello world").start()
val firstError = firstProcess.errorStream.readBytes().decodeToString()
val firstResult = firstProcess.inputStream.readBytes().decodeToString()

0

পূর্ববর্তী উত্তর থেকে অভিযোজিত:

public static String execCmdSync(String cmd, CmdExecResult callback) throws java.io.IOException, InterruptedException {
    RLog.i(TAG, "Running command:", cmd);

    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(cmd);

    //String[] commands = {"system.exe", "-get t"};

    BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
    BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));

    StringBuffer stdOut = new StringBuffer();
    StringBuffer errOut = new StringBuffer();

    // Read the output from the command:
    System.out.println("Here is the standard output of the command:\n");
    String s = null;
    while ((s = stdInput.readLine()) != null) {
        System.out.println(s);
        stdOut.append(s);
    }

    // Read any errors from the attempted command:
    System.out.println("Here is the standard error of the command (if any):\n");
    while ((s = stdError.readLine()) != null) {
        System.out.println(s);
        errOut.append(s);
    }

    if (callback == null) {
        return stdInput.toString();
    }

    int exitVal = proc.waitFor();
    callback.onComplete(exitVal == 0, exitVal, errOut.toString(), stdOut.toString(), cmd);

    return stdInput.toString();
}

public interface CmdExecResult{
    void onComplete(boolean success, int exitVal, String error, String output, String originalCmd);
}

0

খুব সুন্দর এই পৃষ্ঠায় অন্যান্য স্নিপেটের মতো তবে কেবল একটি ফাংশন জুড়ে জিনিসগুলি সংগঠিত করার জন্য , আমরা এখানে যাচ্ছি ...

String str=shell_exec("ls -l");

ক্লাস ফাংশন:

public String shell_exec(String cmd)
       {
       String o=null;
       try
         {
         Process p=Runtime.getRuntime().exec(cmd);
         BufferedReader b=new BufferedReader(new InputStreamReader(p.getInputStream()));
         String r;
         while((r=b.readLine())!=null)o+=r;
         }catch(Exception e){o="error";}
       return o;
       }

-1

InputStreamরানটাইমের পড়ার চেষ্টা করুন :

Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-send", argument};
Process proc = rt.exec(commands);
BufferedReader br = new BufferedReader(
    new InputStreamReader(proc.getInputStream()));
String line;
while ((line = br.readLine()) != null)
    System.out.println(line);

proc.getErrorStream()প্রক্রিয়াটি ত্রুটি আউটপুট প্রিন্ট করে থাকলে আপনার ত্রুটি স্ট্রিম ( ) পড়তেও পারে। আপনি যদি ব্যবহার করেন তবে ত্রুটি স্ট্রিমটিকে ইনপুট স্ট্রিমে পুনর্নির্দেশ করতে পারেনProcessBuilder

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.