প্রথমত, আমি লাইনটি প্রতিস্থাপন করার পরামর্শ দেব
Process process = Runtime.getRuntime ().exec ("/bin/bash");
লাইন দিয়ে
ProcessBuilder builder = new ProcessBuilder("/bin/bash");
builder.redirectErrorStream(true);
Process process = builder.start();
প্রসেসবিল্ডার জাভা 5-এ নতুন এবং বাহ্যিক প্রক্রিয়াগুলি সহজতর করে তোলে। আমার মতে, এর সবচেয়ে উল্লেখযোগ্য উন্নতি Runtime.getRuntime().exec()
হ'ল এটি আপনাকে শিশু প্রক্রিয়াটির স্ট্যান্ডার্ড ত্রুটিটিকে তার স্ট্যান্ডার্ড আউটপুটে পুনর্নির্দেশের অনুমতি দেয়। এর অর্থ আপনার কাছে কেবল একটি InputStream
পড়তে হবে। এর আগে, স্ট্যান্ডার্ড আউটপুট বাফার ফাঁকা থাকাকালীন (বাচ্চার প্রক্রিয়াটি স্তব্ধ হয়ে থাকতে পারে) বা তদ্বিপরীতভাবে আপনার দুটি পৃথক থ্রেড থাকতে হবে, একটি থেকে পড়া stdout
এবং একটি থেকে পড়া fromstderr
এরপরে, লুপগুলি (যার মধ্যে আপনার দুটি রয়েছে)
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
reader
প্রক্রিয়াটির স্ট্যান্ডার্ড আউটপুট থেকে পড়া যখন ফাইল-এর-শেষে ফিরে আসে কেবল তখনই প্রস্থান করুন। bash
প্রক্রিয়াটি যখন প্রস্থান করে তখনই এটি ঘটে । প্রক্রিয়াটি থেকে আর কোনও আউটপুট না উপস্থিত হওয়ার কারণে যদি এটি ঘটে তখন ফাইলের শেষের দিকে ফিরে আসবে না। পরিবর্তে, এটি প্রক্রিয়া থেকে আউটপুট পরবর্তী লাইন জন্য অপেক্ষা করবে এবং এটি এই পরবর্তী লাইন না হওয়া পর্যন্ত ফিরে না।
যেহেতু আপনি এই লুপটিতে পৌঁছানোর আগে প্রক্রিয়াটিতে দুটি লাইন ইনপুট প্রেরণ করছেন, সুতরাং এই দুটি লুপের মধ্যে প্রথমটি স্তব্ধ হয়ে যাবে যদি এই দুটি লাইন ইনপুট পরে প্রক্রিয়াটি বের না হয়। এটি অন্য লাইন পড়ার অপেক্ষা করে সেখানে বসে থাকবে, তবে এটি পড়ার জন্য আর কোনও লাইন আর থাকবে না।
আমি আপনার উত্স কোডটি সংকলন করেছি (এই মুহুর্তে আমি উইন্ডোজটিতে আছি, তাই আমি এর সাথে প্রতিস্থাপন /bin/bash
করেছি cmd.exe
, তবে নীতিগুলি একই হওয়া উচিত) এবং আমি পেয়েছি যে:
- দুটি লাইনে টাইপ করার পরে, প্রথম দুটি কমান্ডের আউটপুট উপস্থিত হয়, কিন্তু তারপরে প্রোগ্রামটি স্তব্ধ হয়ে যায়,
- যদি আমি টাইপ করি, বলি,
echo test
এবং তারপরে exit
, cmd.exe
প্রক্রিয়াটি প্রস্থান হওয়ার পরে প্রোগ্রামটি এটি প্রথম লুপ থেকে বের করে দেয়। প্রোগ্রামটি তখন ইনপুটটির অন্য একটি লাইন জিজ্ঞাসা করে (যা উপেক্ষা করা হয়), শিশু প্রক্রিয়া ইতিমধ্যে উপস্থিত হয়ে যাওয়ার পরে সরাসরি দ্বিতীয় লুপটি এড়িয়ে যায় এবং তারপরে নিজেই উপস্থিত হয়।
- যদি আমি টাইপ করি
exit
এবং তারপরে echo test
পাইপ বন্ধ হওয়ার অভিযোগ পেয়ে আমি একটি আইওএক্সেপশন পেয়ে যাই। এটি আশা করা যায় - ইনপুটটির প্রথম লাইনটি প্রক্রিয়াটি প্রস্থান করেছিল এবং দ্বিতীয় লাইনটি প্রেরণের কোথাও নেই।
আমি এমন একটি কৌশল দেখেছি যা আপনি যা চান বলে মনে হয় তার অনুরূপ কিছু করে, একটি প্রোগ্রামে আমি কাজ করতাম। এই প্রোগ্রামটি বেশ কয়েকটি শেল রাখে, সেগুলিতে কমান্ড চালায় এবং এই কমান্ডগুলি থেকে আউটপুট পড়ে। ব্যবহৃত কৌশলটি সর্বদা একটি 'ম্যাজিক' লাইন লিখতে ছিল যা শেল কমান্ডের আউটপুটটির শেষ চিহ্নিত করে এবং শেলকে পাঠানো কমান্ড থেকে আউটপুট কখন শেষ হয়েছিল তা নির্ধারণ করতে এটি ব্যবহার করে।
আমি আপনার কোডটি নিয়েছি এবং writer
নীচের লুপটির সাথে নির্ধারিত রেখার পরে আমি সমস্ত কিছু প্রতিস্থাপন করেছি :
while (scan.hasNext()) {
String input = scan.nextLine();
if (input.trim().equals("exit")) {
writer.write("exit\n");
} else {
writer.write("((" + input + ") && echo --EOF--) || echo --EOF--\n");
}
writer.flush();
line = reader.readLine();
while (line != null && ! line.trim().equals("--EOF--")) {
System.out.println ("Stdout: " + line);
line = reader.readLine();
}
if (line == null) {
break;
}
}
এটি করার পরে, আমি নির্ভরযোগ্যভাবে কয়েকটি কমান্ড চালাতে পারি এবং প্রতিটি থেকে আউটপুট স্বতন্ত্রভাবে আমার কাছে ফিরে আসতে পারে।
echo --EOF--
শেলের কাছে প্রেরিত লাইনে দুটি কমান্ড রয়েছে যাতে কমান্ড --EOF--
থেকে ত্রুটির ফলেও কমান্ড থেকে আউটপুট সমাপ্ত হয় তা নিশ্চিত করা যায় ।
অবশ্যই, এই পদ্ধতির সীমাবদ্ধতা রয়েছে। এই সীমাবদ্ধতা অন্তর্ভুক্ত:
- যদি আমি কোনও কমান্ড প্রবেশ করি যা ব্যবহারকারীর ইনপুট (যেমন অন্য একটি শেল) এর জন্য অপেক্ষা করে, প্রোগ্রামটি হ্যাঙ্গ হয়ে যায়,
- এটি ধরে নেওয়া হয় যে শেল দ্বারা চালিত প্রতিটি প্রক্রিয়া একটি নতুন লাইন দিয়ে তার আউটপুট শেষ করে,
- শেল দ্বারা চালিত কমান্ডটি একটি লাইন লেখার জন্য ঘটলে এটি কিছুটা বিভ্রান্ত হয়ে পড়ে
--EOF--
।
bash
একটি সিনট্যাক্স ত্রুটির প্রতিবেদন করে এবং যদি আপনি কোনও মিল না দিয়ে কিছু পাঠ্য প্রবেশ করেন তবে প্রস্থান করে )
।
আপনি যদি নির্ধারিত টাস্ক হিসাবে চালানোর কথা ভাবছেন তবে তা কোনও কমান্ড বা একটি ছোট্ট কমান্ডের মধ্যে সীমাবদ্ধ থাকবে যা কখনই এ জাতীয় রোগতাত্ত্বিক পদ্ধতিতে আচরণ করবে না যদি এই পয়েন্টগুলি আপনার কাছে কিছু না আসে।
সম্পাদনা : লিনাক্স এ চালানোর পরে প্রস্থান হ্যান্ডলিং এবং অন্যান্য ছোটখাটো পরিবর্তনগুলি উন্নতি করুন।