forলুপ এখানে জরিমানা। তবে নোট করুন যে ফাইলটি মেশিনের নামগুলি ধারণ করে কারণ এতে কোনও শ্বেতক্ষেত্রের অক্ষর বা গ্লোববিং অক্ষর নেই। সাধারণ for x in $(cat file); do …রেখাগুলির উপরে পুনরাবৃত্তি করার জন্য কাজ করে না file, কারণ শেলটি প্রথমে cat fileযে কোনও জায়গাতেই সাদা স্থান রয়েছে কমান্ড থেকে আউটপুট বিভক্ত করে এবং তারপরে প্রতিটি শব্দকে \[?*গ্লোব প্যাটার্ন হিসাবে বিবেচনা করে তাই আরও প্রসারিত করা হয়। আপনি for x in $(cat file)যদি এতে কাজ করেন তবে আপনি নিরাপদ করতে পারেন:
set -f
IFS='
'
for x in $(cat file); do …
সম্পর্কিত পড়া: নামে ফাঁকা ফাইল দিয়ে লুপিং? ; ব্যাশে ভেরিয়েবল থেকে লাইনে কীভাবে পড়তে পারি? ; পরিবর্তে কেন while IFS= readএত ঘন ঘন ব্যবহার করা হয় IFS=; while read..? মনে রাখবেন যে ব্যবহার while readকরার সময়, লাইনগুলি পড়ার নিরাপদ বাক্য গঠন while IFS= read -r line; do …।
এখন আসুন আপনার while readপ্রয়াসে কী ভুল হয় তা ফিরে আসুন । সার্ভার তালিকা ফাইল থেকে পুনঃনির্দেশ পুরো লুপের জন্য প্রযোজ্য। সুতরাং যখন sshরান, তার মান ইনপুট আসে ফাইল থেকে। Ssh ক্লায়েন্ট জানতে পারে না যে কখন দূরবর্তী অ্যাপ্লিকেশনটি এর স্ট্যান্ডার্ড ইনপুট থেকে পড়তে চাইতে পারে। সুতরাং যত তাড়াতাড়ি ssh ক্লায়েন্ট কিছু ইনপুট লক্ষ্য করে, এটি সেই ইনপুটটি দূরবর্তী দিকে প্রেরণ করে। সেখানকার ssh সার্ভারটি তখন এটি ইনপুটটি রিমোট কমান্ডে ফিড করতে প্রস্তুত। আপনার ক্ষেত্রে, রিমোট কমান্ডটি কোনও ইনপুট কখনই পড়ে না, তাই ডেটাটি ফেলে দেওয়া হয়, তবে ক্লায়েন্ট পক্ষ এটি সম্পর্কে কিছুই জানে না। কাজের সাথে আপনার প্রচেষ্টা echoকারণ echoকোনও ইনপুট কখনই পড়ে না, এটি এর স্ট্যান্ডার্ড ইনপুটটি একা ফেলে দেয়।
আপনি এড়াতে পারেন এমন কয়েকটি উপায়। আপনি -nবিকল্পটি সহ এসএসএসকে স্ট্যান্ডার্ড ইনপুট থেকে না পড়তে বলতে পারেন ।
while read server; do
ssh -n $server "uname -a"
done < /home/kenny/list_of_servers.txt
-nআসলে বিকল্প বলে sshথেকে তার ইনপুট পুনর্নির্দেশ করতে /dev/null। আপনি শেল স্তরে এটি করতে পারেন এবং এটি কোনও কমান্ডের জন্য কাজ করবে।
while read server; do
ssh $server "uname -a" </dev/null
done < /home/kenny/list_of_servers.txt
এড়ানোর SSH এর ইনপুট ফাইল থেকে আসছে একটি প্রলুব্ধকর পদ্ধতির উপর ফেরৎ করা হয় readকমান্ড প্রয়োগ করুন: while read server </home/kenny/list_of_servers.txt; do …। এটি কাজ করবে না, কারণ এটি প্রতিবার readকমান্ড কার্যকর হওয়ার সাথে সাথে ফাইলটি আবার খোলার কারণ হয় (সুতরাং এটি ফাইলটির প্রথম লাইনটি বার বার পড়তে পারে)। লুপটির সময় পুনঃনির্দেশটি পুরোপুরি হওয়া দরকার যাতে লুপের সময়কালের জন্য ফাইলটি একবার খোলায়।
সাধারণ সমাধান হ'ল স্ট্যান্ডার্ড ইনপুট ব্যতীত কোনও ফাইল বর্ণনাকারীর লুপকে ইনপুট সরবরাহ করা। শেলটিতে ফেরি ইনপুট এবং একটি বর্ণনাকারী সংখ্যার থেকে অন্য বর্ণনায় আউটপুট তৈরি হয়। এখানে, আমরা ফাইল বর্ণনাকারী 3 এ ফাইলটি খুলি এবং ফাইল বিবরণকারী 3 থেকে readকমান্ডের স্ট্যান্ডার্ড ইনপুটটি পুনর্নির্দেশ করি The
while read server <&3; do
ssh $server "uname -a"
done 3</home/kenny/list_of_servers.txt
ব্যাশে, readকমান্ডের একটি পৃথক ফাইল বর্ণনাকারী থেকে পড়ার জন্য একটি নির্দিষ্ট বিকল্প রয়েছে, যাতে আপনি লিখতে পারেন read -u3 server।
সম্পর্কিত পড়া: ফাইল বর্ণনাকারী এবং শেল স্ক্রিপ্টিং ; আপনি কখন অতিরিক্ত ফাইল বর্ণনাকারী ব্যবহার করবেন?