ট্র্যাপ কমান্ড ব্যবহার করে কীভাবে ত্রুটি ট্রিগার করা যায়


13

আমি উবুন্টু 12.04.2 ব্যবহার করছি। আমি আমার শেল স্ক্রিপ্টে অস্বাভাবিক বা ত্রুটি ক্যাপচারের জন্য "ট্র্যাপ" কমান্ডটি ব্যবহার করার চেষ্টা করছি তবে আমি নিজেও "ত্রুটি" প্রস্থানটি ট্রিগার করার চেষ্টা করছি।

আমি প্রস্থান 1 টি চেষ্টা করেছি, তবে এটি "ত্রুটি" সংকেতকে ট্রিগার করবে না।

#!/bin/bash

func()
{
    exit 1
}

trap "echo hi" INT TERM ERR
func

নিশ্চিতভাবে কীভাবে "ত্রুটি" থেকে বেরিয়ে যাওয়ার সংকেতটিকে ম্যানুয়ালি ট্রিগার করবেন?

উত্তর:


20

ERRযখন শেল নিজেই একটি নন-জিরো ত্রুটি কোডের মাধ্যমে প্রস্থান করে ফাঁদ কোড চালানোর জন্য করা হয় না, কিন্তু যখন যে শেল দ্বারা কোনো কমান্ড রান করে একটি অংশ নয় শর্ত (মত if cmd..., অথবা cmd || ...একটি অ-শূন্য দিয়ে ...) প্রস্থানের প্রস্থান স্থিতি ( set -eশেল থেকে বেরিয়ে আসার কারণ হিসাবে একই পরিস্থিতি )।

যদি আপনি শূন্য-বহির্গমন স্থিতি সহ শেল থেকে প্রস্থান করার সময় কোডটি চালাতে চান তবে আপনার EXITপরিবর্তে একটি ফাঁদ যুক্ত করে $?সেখানে চেক করতে হবে:

trap '[ "$?" -eq 0 ] || echo hi' EXIT

তবে নোট করুন যে কোনও আটকে থাকা সংকেতের উপরে, সিগন্যাল ট্র্যাপ এবং এক্সিট ট্র্যাপ উভয়ই চালিত হবে, সুতরাং আপনি এটি এর মতো করতে চাইতে পারেন:

unset killed_by
trap 'killed_by=INT;exit' INT
trap 'killed_by=TERM;exit' TERM
trap '
  ret=$?
  if [ -n "$killed_by" ]; then
    echo >&2 "Ouch! Killed by $killed_by"
    exit 1
  elif [ "$ret" -ne 0 ]; then
    echo >&2 "Died with error code $ret"
  fi' EXIT

অথবা $((signum + 128))সিগন্যালের মতো প্রস্থান স্থিতি ব্যবহার করতে :

for sig in INT TERM HUP; do
  trap "exit $((128 + $(kill -l "$sig")))" "$sig"
done
trap '
  ret=$?
  [ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"' EXIT

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

unset killed_by
for sig in INT QUIT TERM HUP; do
  trap "exit $((128 + $(kill -l "$sig"))); killed_by=$sig" "$sig"
done
trap '
  ret=$?
  [ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"
  if [ -n "$killed_by" ]; then
    trap - "$killed_by" # reset handler
    # ulimit -c 0 # possibly disable core dumps
    kill -s "$killed_by" "$$"
  else
    exec "$ret"
  fi' EXIT

আপনি যদি ERRফাঁদে আগুন জ্বালাতে চান তবে একটি শূন্য-বহির্গমন প্রস্থান হিসাবে falseবা এর মতো একটি কমান্ড চালান test


6

ব্যবহারের প্রত্যাবর্তন না প্রস্থান করুন, একটি ফাংশন থেকে প্রস্থানে অবস্থা সেট করার জন্য (ফাংশন পড়ে-থ্রু একটি ফিরতি ছাড়া যদি, অবস্থা যে গত বিবৃতির মৃত্যুদন্ড কার্যকর করা হয়।) আপনি প্রতিস্থাপন তাহলে returnজন্য exitপ্রশ্ন উদাহরণে, এটি হিসাবে কাজ করবে আমি মনে করি আপনি উদ্দেশ্য করেছেন: ফাঁদটি ইআরআর সিউডো-সিগন্যালে ট্রিগার করা হবে এবং 'হাই' মুদ্রণ করা হবে। অতিরিক্ত বিবেচনার জন্য, এটি চেষ্টা করুন:

#!/bin/bash

func()
{
    echo 'in func'
    return 99
    echo 'still in func'
}

trap 'echo "done"' EXIT
trap 'status=$?; echo "error status is $status"; trap - EXIT; exit $status' ERR
func
echo 'returned from func'

আপনি 0 টি ফিরে আসা, ERR ফাঁদটি সম্পর্কে মন্তব্য করা, ERR হ্যান্ডলারের মধ্যে থাকা Exit ফাঁদ বাতিল না করা, ERR হ্যান্ডলার থেকে প্রস্থান না করা, বা রিটার্নটি সরিয়ে এবং falseশেষ বিবৃতি হিসাবে মজাদার বিভিন্ন রূপ পরিবর্তন করতে পারেন।

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