পড়ার সময় শেল স্ক্রিপ্ট প্রথম লাইনের পরে থামবে


107

আমার নীচের শেল স্ক্রিপ্ট রয়েছে। টার্গেট ফাইলের প্রতিটি লাইন (যার পথ স্ক্রিপ্টের ইনপুট প্যারামিটার) এর মধ্য দিয়ে লুপ করা এবং প্রতিটি লাইনের বিপরীতে কাজ করা উদ্দেশ্য। এখন লক্ষ্যমাত্রার ফাইলটিতে এটি প্রথম লাইনের সাথে কাজ করে এবং লাইনটি প্রক্রিয়া করার পরে থামবে। আমার স্ক্রিপ্টে কিছু ভুল আছে?

#!/bin/bash
# SCRIPT: do.sh
# PURPOSE: loop thru the targets 

FILENAME=$1
count=0

echo "proceed with $FILENAME"

while read LINE; do
   let count++
   echo "$count $LINE"
   sh ./do_work.sh $LINE
done < $FILENAME

echo "\ntotal $count targets"

ইন do_work.sh, আমি কয়েক sshকমান্ড চালাচ্ছি ।


1
আপনার স্ক্রিপ্টটি ঠিক আছে, তবে do_work.sh- এর সাথে কিছু ভুল হতে পারে
স্লাইডসোর্ট

2
হ্যাঁ, এটি সমস্ত ইনপুট খেয়ে ফেলতে পারে, বা এটি হিসাবে আহ্বান করা যেতে পারে sourceএবং কেবল প্রস্থান হতে পারে বা exec। তবে এই কোডটি খাঁটি মনে হচ্ছে না, ওপি লক্ষ্য করবে যে প্রতিধ্বনিটি -eসঠিকভাবে লাইন ফিড প্রদর্শন করতে হবে ...
মাইকেল ক্রেলিন - হ্যাকার

3
না do_work.shচালানোর sshকোনো সুযোগ দ্বারা?
ডগবনে

1
হ্যাঁ, do_work.sh একটি দম্পতি ssh কমান্ড চালায়। এ সম্পর্কে বিশেষ কিছু?
বিসিবিশপ

1
বেটার আপনি দেখাতে do_work.shউৎস এবং এছাড়াও চালানোর do.shসঙ্গে set -xডিবাগ করতে।
কুলা

উত্তর:


178

সমস্যাটি হ'ল আদেশগুলি do_work.shচালায় sshএবং ডিফল্টরূপে sshস্টিডিন থেকে পড়ে যা আপনার ইনপুট ফাইল। ফলস্বরূপ, আপনি কেবল প্রথম লাইনটি প্রক্রিয়াকৃত দেখেন, কারণ sshবাকী ফাইলটি এবং আপনার সময় লুপটি শেষ হয়ে যায়।

এটি প্রতিরোধ করতে , স্ট্যান্ডিনের পরিবর্তে এটি পড়তে -nআপনার sshকমান্ডের বিকল্পটি পাস করুন /dev/null


1
খুব দরকারী, আমাকে এই zsh অনেলাইনার চালাতে সহায়তা করেছে: বিড়াল হোস্টস | হোস্ট পড়ার সময়; do ssh $ হোস্ট do_something; সম্পন্ন
ইঁদুর

3
আপনি @rat এখনও এড়াতে চান বেহুদা catআপনি ভাবেন যে বিশেষত কোনও রডেন্ট এ সম্পর্কে সতর্ক থাকবে।
ট্রিপলি

while read host ; do $host do_something ; done < /etc/hostsএটি এড়াতে হবে। এটি বেশ একটি জীবন রক্ষাকারী, ধন্যবাদ!
ইঁদুর

httpieডিফল্টরূপে STDIN পড়ার আর একটি আদেশ হ'ল এবং যখন ব্যাশ বা ফিশ লুপের ভিতরে ডাকা হয় তখন একই আচরণে ভুগবে। উপরে হিসাবে http --ignore-stdinমানক ইনপুট ব্যবহার করুন বা সেট করুন /dev/null
রমন

12

আরও সাধারণভাবে, এমন একটি কর্মক্ষেত্র যা নির্দিষ্ট নয় sshএটি কোনও আদেশের জন্য স্ট্যান্ডার্ড ইনপুট পুনর্নির্দেশ করা যা অন্যথায় whileলুপের ইনপুট গ্রহণ করতে পারে।

while read -r LINE; do
   let count++
   echo "$count $LINE"
   sh ./do_work.sh "$LINE" </dev/null
done < "$FILENAME"

সংযোজন </dev/nullএখানে গুরুত্বপূর্ণ পয়েন্ট (যদিও সংশোধন করা উদ্ধৃতিটি কিছুটা গুরুত্বপূর্ণও; শেল ভেরিয়েবলের চারপাশে উদ্ধৃতি কখন গুটিয়ে রাখতে হয় তা দেখুন? ) আপনি যদি না read -rবিশেষভাবে উত্তরাধিকারের কিছুটা স্বতন্ত্র আচরণের প্রয়োজন বোধ করেন তবে আপনি ব্যবহার করতে চান -r

কিছু প্রকারের নির্দিষ্ট ধরণের যা অন্য sshকোনও sshকমান্ডের স্ট্যান্ডার্ড ইনপুট বেঁধে রাখা আছে তা নিশ্চিত করা, উদাহরণস্বরূপ পরিবর্তন করে

ssh otherhost some commands here

পরিবর্তে এখানে একটি নথি থেকে কমান্ডগুলি পড়ার জন্য, যা স্বাচ্ছন্দ্যে (এই নির্দিষ্ট দৃশ্যের জন্য) sshআদেশগুলির জন্য স্ট্যান্ডার্ড ইনপুটটিকে যুক্ত করে:

ssh otherhost <<'____HERE'
    some commands here
____HERE

5

অন্য প্রোগ্রামে আউটপুট পাইপ করার সময় HEREdoc ব্যবহার করার সময় ssh -n বিকল্পটি এসএসএসের প্রস্থান স্থিতি পরীক্ষা করতে বাধা দেয়। সুতরাং স্টিডিন হিসাবে / ডিভ / নাল ব্যবহার পছন্দ করা হয়।

#!/bin/bash
while read ONELINE ; do
   ssh ubuntu@host_xyz </dev/null <<EOF 2>&1 | filter_pgm 
   echo "Hi, $ONELINE. You come here often?"
   process_response_pgm 
EOF
   if [ ${PIPESTATUS[0]} -ne 0 ] ; then
      echo "aborting loop"
      exit ${PIPESTATUS[0]}
   fi
done << input_list.txt

এটা কোন মানে নেই। <<EOFঅগ্রাহ্য </dev/nullফেরৎ। এর <<পরে পুনঃনির্দেশটি doneভুল।
ট্রিপলি 25'19

1

আমার সাথে এটি ঘটছিল কারণ আমার ছিল set -eএবং একটি grepলুপ কোনও আউটপুট ছাড়াই ফিরে আসছিল (যা একটি শূন্য-ত্রুটি কোড দেয়)।

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