শেল স্ক্রিপ্টের একটি অংশ ব্যর্থ হলে কীভাবে প্রস্থান করবেন?


51

এর একটি অংশ ব্যর্থ হলে আমি কীভাবে শেল স্ক্রিপ্ট লিখতে পারি? উদাহরণস্বরূপ, যদি নিম্নলিখিত কোড স্নিপেট ব্যর্থ হয়, তবে স্ক্রিপ্টটি প্রস্থান করা উচিত।

n=0
until [ $n -ge 5 ]
do
  gksu *command* && break
  n=$[$n+1]
  sleep 3

উত্তর:


88

একটি পন্থা set -eআপনার স্ক্রিপ্টের শুরুতে যুক্ত করা হবে । এর অর্থ (থেকে help set):

  -e  Exit immediately if a command exits with a non-zero status.

সুতরাং আপনার কোনও আদেশ যদি ব্যর্থ হয় তবে স্ক্রিপ্টটি প্রস্থান করবে।

বিকল্পভাবে, আপনি exitসম্ভাব্য ব্যর্থতার পয়েন্টগুলিতে সুস্পষ্ট বক্তব্যগুলি যুক্ত করতে পারেন :

command || exit 1

5
আমি (এবং বাশ উইকি ) লোকেরা বরং (নকশা আইএমও দ্বারা ভাঙা) set -eবৈশিষ্ট্যটি ব্যবহার না করে সঠিক ত্রুটি পরিচালনার ক্ষেত্রে কিছুটা চিন্তাভাবনা করব । যদিও এটি এখানে সত্যই প্রয়োগ হয় না। কমান্ডটি চালানোর জন্য 5 টি ব্যর্থ চেষ্টার পরে ওপি স্ক্রিপ্টটি থেকে বেরিয়ে যেতে চায়।
স্টাফেন চেজেলাস

1
@ স্টাফেনচাজেলাস এটি ভেঙে গেছে কিনা তা নিয়ে আমি আপনার সাথে তর্ক করব না, আমি নিশ্চিত যে আপনি ঠিক আছেন। যাইহোক, ওপিতে জিজ্ঞাসা করা হয়েছিল "শেল স্ক্রিপ্টটি কীভাবে রচনা করতে পারে যা এর একটি অংশ ব্যর্থ হয়?", আপনি কী মনে করেন এটি 5 ব্যর্থতার পরে প্রস্থান করার বিষয়ে?
টেরডন

কারণ আমি অন্য কোনও উপায়ে প্রশ্নটি ব্যাখ্যা করার মতো ভাবতে পারি না।
স্টাফেন চেজেলাস

1
@ স্টাফেনচেজেলাস আপনি ভাল থাকতে পারেন। আমি এটি আক্ষরিকভাবে ব্যাখ্যা করেছিলাম: এর কোনও অংশ ব্যর্থ হলে কীভাবে পুরো স্ক্রিপ্টটি প্রস্থান করতে পারে। এবং আমি set -eএটি করতে একমাত্র উপায়।
টেরডন

এই স্ক্রিপ্ট স্নিপেটে, কমান্ডগুলি যে ট্রিগার করতে পারে set -eতা হ'ল sleep( breakএকটি বিশেষ বিল্টিন হওয়ায় বেশিরভাগ শেলগুলিতে ব্যর্থতার ফলে স্ক্রিপ্টটি প্রস্থান করতে পারে, কমান্ডগুলি ifবা বামে &&প্রভাবিত হয় না set -e, কেবল পঠনযোগ্য n=...হলে ব্যর্থ হতে পারে n, তবে তারপরে এটি set -eপাশাপাশি ছাড়াই স্ক্রিপ্ট থেকে বেরিয়ে আসবে ), যাতে ব্যাখ্যাটি বেশ অসম্ভব বলে মনে হয়। আমি সম্মত হ'ল প্রশ্নটি খারাপভাবে বলা হচ্ছে।
স্টাফেন চেজেলাস

17

আপনি কীওয়ার্ডটি ব্যবহার করে যে কোনও জায়গায় কোনও স্ক্রিপ্ট থেকে বেরিয়ে আসতে পারেন exit। আপনার প্রোগ্রামটি বা কীভাবে আপনার স্ক্রিপ্টটি ব্যর্থ হয়েছে, উদাহরণস্বরূপ exit 1বা exit 2ইত্যাদির জন্য এটি নির্ধারণের জন্য আপনি একটি প্রস্থান কোডও নির্দিষ্ট করতে পারেন (কনভেনশন অনুসারে, প্রস্থান কোড 0 সাফল্যের জন্য এবং 0 এর চেয়ে বড় কিছু ব্যর্থতা নির্দেশ করে; তবে কনভেনশন দ্বারা, প্রস্থানও 127 এর উপরে কোডগুলি অস্বাভাবিক সমাপ্তির জন্য সংরক্ষিত (যেমন একটি সংকেত দ্বারা))।

জেনেরিক নির্মাণ ব্যর্থতা থেকে প্রস্থান করার জন্য হয়

if [ failure condition ]; then
    exit n
fi

উপযুক্ত failure conditionএবং n। তবে নির্দিষ্ট পরিস্থিতিতে আপনি আলাদাভাবে এগিয়ে যেতে পারেন। এখন আপনার মামলার জন্য আমি আপনার প্রশ্নের ব্যাখ্যা করছি যে যদি পাঁচটি নিমন্ত্রণের মধ্যে কোনওটি gksuব্যর্থ হয়, তবে আপনি প্রস্থান করতে চাইছেন। একটি উপায় এই জাতীয় ফাংশন ব্যবহার করা হয়

function try_command {
    for i in 1 2 3 4 5 ; do
        if gksu command ; then
            return 0
        fi
    fi
    exit 1
}

এবং তারপরে, লুপটি ডেকে আনুন try_command

আপনার প্রশ্নের সমাধান করার জন্য আরও (আরও) উন্নত বা পরিশীলিত উপায় রয়েছে। তবে, স্টিফেনের সমাধানের চেয়ে উপরের সমাধানটি প্রাথমিকভাবে আরও অ্যাক্সেসযোগ্য।


10
attempt=0
until gksu command; do
  attempt=$((attempt + 1))
  if [ "$attempt" -gt 5 ]; then
    exit 1
  fi
done

exitস্ক্রিপ্টটি না ডাকলে স্ক্রিপ্টটি প্রস্থান করে। যদি স্ক্রিপ্টের যে অংশ একটি subshell হয়, উদাহরণস্বরূপ এটা মধ্যে কারণ (...)বা $(...)বা নল-লাইন অংশ, তাহলে এটি শুধুমাত্র থেকে প্রস্থান করা হবে যে subshell

সেক্ষেত্রে আপনি যদি স্ক্রিপ্টটি সাব-শেল ছাড়াও প্রস্থান করতে চান তবে আপনাকে exitসেই সাবশেলটি থেকে বেরিয়ে আসার জন্য কল করতে হবে ।

উদাহরণস্বরূপ, এখানে সাবস্কেলের 2 নেস্টেড স্তর সহ:

(
  life=hard
  output=$(
    echo blah
    [ "$life" = easy ] || exit 1 # exit subshell
    echo blih not run
  ) || exit # if the subshell exits with a non-zero exit status,
            # exit as well with the same exit status

  echo not run either
) || exit # if the subshell exits with a non-zero exit status,
          # exit as well with the same exit status

সাবস্কেল কোনও পাইপলাইনের অংশ হলে এটি আরও জটিল হয়ে উঠতে পারে। bashএকটি বিশেষ হয়েছে $PIPESTATUSএরে, অনুরূপ zsh'র $pipestatusএক যে আপনি এখানে সাহায্য করতে পারেন:

{
   echo foo
   exit 1
   echo bar
} | wc -c
subshell_ret=${PIPESTATUS[0]}
if [ "$subshell_ret" -ne 0 ]; then
  exit "$subshell_ret"
fi

3

ট্র্যাপ সিগন্যাল পাওয়ার পরে একটি ক্রিয়া সম্পাদন করবে।

trap "echo EXIT;  exit" 0
trap "echo HUP;   exit" 1
trap "echo CTL-C; exit" 2
trap "echo QUIT;  exit" 3
trap "echo ERR;   exit" ERR
n=0
until [ $n -ge 5 ]
do
  n=$[$n+1]
  echo $n
  sleep 3
done

এটি চালান এবং এটিকে স্বাভাবিকভাবে প্রস্থান করতে দিন। এটি 0 সিগন্যালে আটকা পড়ে।

EXIT

এটি আবার চালাও এবং ^ C এর সাথে বাধা দিন। এটি সিগন্যাল 2 এবং সিগন্যাল 0 উভয়কেই ফাঁদে ফেলে।

CTL-C
EXIT

একটি শূন্য-বহির্গমন প্রস্থান স্থিতি ERR এ ফাঁদে যাবে

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