আপনি যদি রুবি থেকে একটি এক্সটার্নাল কমান্ড রান করতে চান...
...যেন wkhtmltopdf একটি HTML ফাইল কে PDF-এ কনভার্ট করতে।
কয়েকটি রুবি মেথড আছে যা আপনি ব্যবহার করতে পারেন।
আপনি কোন মেথড ব্যবহার করছেন তার ওপর নির্ভর করে আপনি ভিন্ন ফলাফল পাবেন।
চলুন এই মেথডগুলো একসাথে এক্সপ্লোর করি!
রুবি System মেথড
রুবি system মেথড হলো এক্সটার্নাল কমান্ড রান করার সবচেয়ে সহজ পদ্ধতি।
এটি এমন দেখায়:
system("ls")
লক্ষ্য করুন system কমান্ড আউটপুট প্রিন্ট করে যেমন তা হয়।
এছাড়া system আপনার রুবি প্রোগ্রামকে কমান্ড শেষ হওয়া পর্যন্ত অপেক্ষা করতে বাধ্য করে।
এটি ট্রাই করুন:
system("sleep 2")
কমান্ড ব্যাকগ্রাউন্ডে রান করার পদ্ধতিও আছে যা আমরা পরে দেখব।
System ৩টি সম্ভাব্য মান রিটার্ন করতে পারে:
trueযদি কমান্ড কাজ করেfalseযদি কমান্ড একটি এরর কোড রিটার্ন করেnilযদি কমান্ড এক্সিকিউশন ফেইল করে (কমান্ড নট ফাউন্ড)
আপনি লাস্ট এক্সটার্নাল কমান্ড যা আপনি রান করেছেন তার এক্সিট স্ট্যাটাস কোড পেতে পারেন $? গ্লোবাল ভেরিয়েবল দিয়ে। এই স্ট্যাটাস কোড আপনাকে কেন কমান্ড ফেইল হয়েছে তার বিষয়ে আরও ইনফরমেশন দিতে পারে।
শেল এক্সপ্যানশন কী?
আপনি যখন system দিয়ে একটি এক্সটার্নাল কমান্ড রান করেন তবে আপনি "শেল এক্সপ্যানশন" ইফেক্ট পাবেন।
শেল এক্সপ্যানশন হলো যখন শেল (sh/bash/zsh) আপনার কমান্ড থেকে কিছু স্পেশাল ক্যারেক্টার (*, ?, এবং [) নেয় এবং সেগুলোকে একটি ফাইল লিস্টে এক্সপ্যান্ড করে।
উদাহরণ:
system("echo *")
এটি করেন্ট ডিরেক্টরির সব ফাইল এবং ফোল্ডার প্রিন্ট করবে।
* কমান্ড রান হওয়ার আগে ফাইল লিস্ট দিয়ে রিপ্লেস হয়ে যায়।
আপনি যদি এই স্পেশাল ক্যারেক্টারগুলোকে যেনই ব্যবহার করতে চান তবে আর্গুমেন্টগুলো ২য় আর্গুমেন্ট হিসেবে পাস করুন system-এর।
এভাবে:
system("echo", "*")
এখন আউটপুট হবে *।
এনভায়রনমেন্ট ভেরিয়েবল কীভাবে ব্যবহার করবেন
আপনি যদি একটি নির্দিষ্ট এনভায়রনমেন্ট ভেরিয়েবল একটি এক্সটার্নাল কমান্ডে পাস করতে চান আপনি প্রথম আর্গুমেন্ট হিসেবে একটি হ্যাশ ব্যবহার করতে পারেন।
এখানে একটি উদাহরণ:
system({"rubyguides" => "best"}, "ruby", "-e p ENV['rubyguides']") # "best"
এটি আপনার রুবি অ্যাপ্লিকেশনের করেন্ট এনভায়রনমেন্টকে পরিবর্তন করবে না।
%x / Kernel#`
আপনি যদি আপনি যে কমান্ড রান করছেন তার আউটপুট পেতে চান, ডিসপ্লে করার বদলে, তবে আপনি %x বা Kernel#` মেথড ব্যবহার করতে পারেন।
এগুলো একই কাজ করে।
এখানে একটি উদাহরণ:
`ls`
%x দিয়ে আরেকটি:
%x|ls|
এই দুটি উদাহরণ ls কমান্ডের আউটপুটসহ একটি স্ট্রিং রিটার্ন করবে।
লক্ষ্য করুন আপনাকে এখনো কমান্ড ফিনিশ হওয়ার জন্য অপেক্ষা করতে হবে যদি না আপনি এটিকে একটি থ্রেডের ভিতরে রান করেন।
Fork + Exec দিয়ে এক্সটার্নাল কমান্ড আলাদা প্রসেসে রান করা
ফর্কিং আপনার করেন্ট প্রসেসের (আপনার রুবি অ্যাপ) একটি কপি তৈরি করে তারপর আপনি সেটি exec দিয়ে অন্য একটি প্রসেসে রিপ্লেস করতে পারেন।
নোট: fork মেথড উইন্ডোজে উপলব্ধ নয়।
এটি ইউনিক্স বিশ্বে একটি জনপ্রিয় প্যাটার্ন।
এটি কীভাবে কাজ করে:
fork { exec("ls") }
এটি ls অন্য একটি প্রসেসে রান করবে এবং এর আউটপুট ডিসপ্লে করবে।
কারণ এই কমান্ড অন্য একটি প্রসেসে চলছে এটি আপনার রুবি অ্যাপকে রান করতে বাধা দেবে না system মেথড বা %x-এর মতো।
গুরুত্বপূর্ণ:
আপনি যদি fork ছাড়া exec ব্যবহার করেন তবে আপনি আপনার করেন্ট প্রসেস রিপ্লেস করবেন।
এর মানে আপনার রুবি প্রোগ্রাম শেষ হয়ে যাবে।
পোপেন মেথড ব্যবহার করে এক্সটার্নাল প্রোগ্রামের সাথে টু-ওয়ে কমিউনিকেশন
আপনাকে যদি দরকার:
- প্রসেসের ওপর আরও কন্ট্রোল
- টু-ওয়ে কমিউনিকেশন
তবে IO.popen মেথডটি আপনার যা খুঁজছেন।
নিচের উদাহরণে আমি popen মেথড ব্যবহার করছি একটি irb প্রসেস লঞ্চ করতে, তারপর কিছু ইনপুট পাঠাতে এবং আউটপুট পড়তে।
এখানে উদাহরণ:
r = IO.popen("irb", "r+") r.write "puts 123 + 1\n" 3.times { puts r.gets } r.write "exit\n"
এই r ভেরিয়েবলটি একটি IO অবজেক্ট, এর মানে আপনি এতে রेگুলার ফাইলের মত লিখতে ও পড়তে পারেন।
popen ব্যবহার করলে আপনার এক্সটার্নাল কমান্ড তার নিজস্ব প্রসেসে রান হবে, তাই আপনাকে এটিকে থ্রেডে রান করতে হবে না।
স্ট্যান্ডার্ড লাইব্রেরি-এ একটি popen3 মেথডও রয়েছে।
রেগুলার popen-এর সাথে পার্থক্য হলো এটি রেগুলার আউটপুট এবং এরর মেসেজকে আলাদা আলাদা IO অবজেক্টে ভাগ করে দেবে।
উপসংহার
আপনি রুবিতে এক্সটার্নাল কমান্ডের সাথে ইন্টারঅ্যাক্ট করার বিভিন্ন পদ্ধতি সম্পর্কে শিখেছেন।
এগুলো দিয়ে সতর্ক रहুন!
যেকোনো ইউজার ইনপুট এই কমান্ডগুলোর মধ্যে পাস করবেন না যদি না আপনি আপনার রুবি অ্যাপে একটি সিকিউরিটি ইস্যু চান।
আপনি যদি কিছু নতুন শিখেন তবে এই আর্টিকেলটি শেয়ার করুন যাতে আরও মানুষ এটিকে দেখতে পারে।
পড়ার জন্য ধন্যবাদ 🙂