"ফাঁদ… INT TERM প্রস্থান" সত্যই প্রয়োজনীয়?


63

ক্লিনআপ কাজের জন্য trapব্যবহারের trap ... INT TERM EXITজন্য অনেক উদাহরণ । তবে তিনটি সিগস্পেকের তালিকা করা কি সত্যিই প্রয়োজনীয়?

ম্যানুয়ালটিতে বলা হয়েছে:

যদি একটি SIGNAL_SPEC হয় এক্সিট (0) এআরজি শেল থেকে প্রস্থান করার সময় কার্যকর করা হয়।

যা আমি বিশ্বাস করি প্রযোজ্য কিনা স্ক্রিপ্ট স্বাভাবিকভাবে সমাপ্ত অথবা কারণ এটি পেয়েছি এটি সমাপ্ত SIGINTবা SIGTERM। একটি পরীক্ষা আমার বিশ্বাসকেও নিশ্চিত করে:

$ cat ./trap-exit
#!/bin/bash
trap 'echo TRAP' EXIT
sleep 3
$ ./trap-exit & sleep 1; kill -INT %1
[1] 759
TRAP
[1]+  Interrupt               ./trap-exit
$ ./trap-exit & sleep 1; kill -TERM %1
[1] 773
TRAP
[1]+  Terminated              ./trap-exit

তাহলে কেন এতগুলি উদাহরণ সমস্তের তালিকা করে INT TERM EXIT? বা আমি কিছু মিস করেছি এবং এমন কোনও ঘটনা আছে যেখানে কোনও একক EXITমিস করবে?


3
এছাড়াও মনে রাখবেন যে INT TERM EXITক্লিনআপ কোডের মতো একটি অনুমানের সাথে দু'বার কার্যকর করা হয় SIGTERMবা SIGINTগ্রহণ করা হয়।
maxschlepzig

উত্তর:


19

POSIX বৈশিষ্ট অবস্থার প্রস্থান করুন ফাঁদ নির্বাহ মাত্র কি তার পরিবেশ যখন এটি কার্যকর মত চেহারা আবশ্যক ফলে সম্পর্কে অনেক না বলা আছে।

ব্যাসবক্সের অ্যাশ শেল-এ, আপনার ট্র্যাপ-প্রস্থান পরীক্ষা সাইন ইন বা সিগনেটারের কারণে প্রস্থান করার আগে 'ট্র্যাপ' প্রতিধ্বনিত করে না। আমি সন্দেহ করব দূরত্বের অন্যান্য শাঁস রয়েছে যেগুলি সেভাবে কাজ করে না।

# /tmp/test.sh & sleep 1; kill -INT %1
# 
[1]+  Interrupt                  /tmp/test.sh
# 
# 
# /tmp/test.sh & sleep 1; kill -TERM %1
# 
[1]+  Terminated                 /tmp/test.sh
# 

3
dashএটি EXITযখন পায় ঠিক তখন ফাঁদে পড়ে না SIGINT/SIGTERM
ম্যাক্সচলেপজিগ

4
zshপাশাপাশি - সুতরাং, সম্ভবত bashএকমাত্র শাঁস যেখানে EXITএটি সংকেতগুলিও মেলে।
maxschlepzig

@maxschlepzig zshউপর ফাঁদ না EXITযখন এটি পায় INT, কিন্তু আপনার এটি পায় এটা আছে TERM। সম্পাদনা: আমি ঠিক লক্ষ্য করেছি যে এটি কতটা পুরানো ছিল ...
জো

27

হ্যাঁ, একটি পার্থক্য আছে।

এই স্ক্রিপ্টটি থেকে প্রস্থান করা হবে যখন আপনি টিপুন Enter, অথবা এটি পাঠাতে SIGINTবা SIGTERM:

trap '' EXIT
echo ' --- press ENTER to close --- '
read response

আপনি যখন চাপবেন তখন এই স্ক্রিপ্টটি প্রস্থান করবে Enter:

trap '' EXIT INT TERM
echo ' --- press ENTER to close --- '
read response

* , বাশ এবং জেড-এ পরীক্ষিত । ( আপনি যখন ট্র্যাপ চালানোর জন্য একটি কমান্ড যুক্ত করেন তখন sh এ কাজ করে না )


@ শ্যাশন যা বলেছিল সেগুলিও রয়েছে: অ্যাশ এবং ড্যাশ সিগন্যালগুলি ফাঁদে ফেলবে না EXIT

সুতরাং, সিগন্যালগুলিকে দৃust়ভাবে পরিচালনা করার জন্য EXIT, পুরোপুরি আটকা পড়া এড়ানো ভাল এবং এরকম কিছু ব্যবহার করুন:

cleanup() {
    echo "Cleaning stuff up..."
    exit
}

trap cleanup INT TERM
echo ' --- press ENTER to close --- '
read var
cleanup

1
ক্লিনআপ সহ সমাধানটি সঠিক কাজটি করে - খুব মার্জিত! এটি mktempকল সহ আমার বাশ স্ক্রিপ্টগুলির একটি প্রতিমা হিসাবে পরিণত হয়েছে ।
বজোর্ন ডাহলগ্রেন

2
এটি কি exitপ্রয়োজনীয় cleanup?
জার্নো

3
আপনার কোডে শেলসক্রিপ্ট ত্রুটি থাকলে এটি অকারণে প্রস্থান করতে পারে যদি এটি কাজ করে না।
আইজডব্লিউ

2
@ আইজডাব্লু: বাশ এবং ক্ষেতে, আপনি এটিERR পরিচালনা করতে ফাঁদে ফেলতে পারেন , তবে এটি বহনযোগ্য নয়
জাজ

5
যখন অন্য শেল এটি কল করে তখন এই সমাধানটি দৃust় নয়। এটি সমবায় প্রস্থানের অপেক্ষার বিষয়টি পরিচালনা করে না ; আপনি trap - INT TERM; kill -2 $$ক্লিনআপের শেষ লাইন হিসাবে চাইবেন , প্যারেন্ট শেলকে বলতে যে এটি অকাল থেকেই বেরিয়েছে। যদি কোনও পিতা-মাতা শেল foobar.sh আপনার স্ক্রিপ্টকে (foo.sh) কল করে এবং তারপরে বার.শকে কল করে, আপনি চান না যে বার.শকে কার্যকর করা হবে যদি আপনার foo.sh এ INT / TERM প্রেরণ করা হয় if trap cleanup EXITএই প্রচারটি স্বয়ংক্রিয়ভাবে পরিচালনা করবে, সুতরাং এটি সবচেয়ে শক্তিশালী আইএমও। এর অর্থ হ'ল cleanupস্ক্রিপ্টের শেষে আপনাকে কল করতে হবে না ।
নিকোলাস পিপিটোন

12

শেষ উত্তরটি সংশোধন করা হচ্ছে, কারণ এতে সমস্যা রয়েছে:

# Our general exit handler
cleanup() {
    err=$?
    echo "Cleaning stuff up..."
    trap '' EXIT INT TERM
    exit $err 
}
sig_cleanup() {
    trap '' EXIT # some shells will call EXIT after the INT handler
    false # sets $?
    cleanup
}
trap cleanup EXIT
trap sig_cleanup INT QUIT TERM

উপরের পয়েন্টগুলি:

INT এবং TERM হ্যান্ডলাররা আমার পরীক্ষা করার সময় আমার জন্য ছেড়ে দেয় না - তারা ত্রুটিটি পরিচালনা করে তারপরে শেলটি প্রস্থান করে ফিরে আসে (এবং এটি খুব অবাক হওয়ার মতো নয়)। সুতরাং আমি নিশ্চিত হয়েছি যে ক্লিনআপটি এরপরে চলে গেছে এবং সংকেতগুলির ক্ষেত্রে সর্বদা একটি ত্রুটি কোড ব্যবহার করে (এবং সাধারণ প্রস্থানের ক্ষেত্রে অন্যথায় ত্রুটি কোড সংরক্ষণ করে)।

ব্যাশের সাহায্যে মনে হয় যে আইএনটি হ্যান্ডলারের সাথে প্রস্থান করাও এক্সিট হ্যান্ডলারটিকে কল করে, তাই আমি প্রস্থান হ্যান্ডলারটি আনপ্রেট করে নিজেকে বলি (যা কোনও আচরণের ক্ষেত্রে নির্বিশেষে কোনও শেলটিতে কাজ করবে)।

আমি প্রস্থানটিকে ফাঁদে ফেলেছি কারণ শেল স্ক্রিপ্টগুলি নীচে পৌঁছানোর আগেই প্রস্থান করতে পারে - সিনট্যাক্স ত্রুটি, সেট-ই এবং একটি ননজারো রিটার্ন, কেবল প্রস্থানকে কল করে। আপনি নীচে পৌঁছতে শেলস্ক্রিপ্টের উপর নির্ভর করতে পারবেন না।

সিকুইটিটিটি সিটিআরএল \ আপনি যদি কখনও চেষ্টা না করে থাকেন। আপনাকে একটি বোনাস coredump দেয়। সুতরাং আমি মনে করি এটি আটকা পড়ার মতো, যদিও এটি কিছুটা অস্পষ্ট।

অতীত অভিজ্ঞতা বলছে যদি আপনি (আমার মতো) সর্বদা বেশ কয়েকবার Ctrl-C টিপেন তবে আপনি কখনও কখনও এটি আপনার শেল স্ক্রিপ্টের ক্লিনআপ অংশের মধ্য দিয়ে অর্ধেক পথ ধরে ফেলেন, সুতরাং এটি আপনার পছন্দ মতো সর্বদা নিখুঁত নয়।


2
আহ্বানকারী মাত্র প্রস্থান কোড হিসেবে 1 পেতে চাই, কোন ব্যাপার কি সংকেত প্রস্থান সৃষ্ট, যখন withour trapআহ্বানকারী SIGINT, SIGTERM জন্য 143, ইত্যাদি তাই আমি ক্যাপচার করবে 130 পেতে এবং তারিখ অনুযায়ী সঠিক প্রস্থান কোড পাস হবে: sig_cleanup() { err=$?; trap '' EXIT; (exit $err); cleanup; }
মুসিফিল

2
আপনি কি trap '' EXIT INT TERMক্লিনআপ ফাংশনটির উদ্দেশ্যটি পরিষ্কার করতে পারেন ? এটি কি আপনি গত অনুচ্ছেদে উল্লিখিত ক্লিনআপের দুর্ঘটনাক্রমে ব্যবহারকারীর বাধা রোধ করার জন্য? অনর্থক নয় EXIT?
ছয়
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.