রুবিতে Ctrl-c ক্যাপচার করা হচ্ছে


107

আমি দীর্ঘ চলমান লিগ্যাসি রুবি প্রোগ্রামটি পাস করেছি, যার অসংখ্য ঘটনা রয়েছে

begin
  #dosomething
rescue Exception => e
  #halt the exception's progress
end

এটি জুড়ে।

প্রতিটি একক সম্ভাব্য ব্যতিক্রম ট্র্যাক না করে এগুলি প্রতিটি পরিচালনা করতে পারে (কমপক্ষে তাত্ক্ষণিকভাবে নয়), আমি এখনও মাঝে মাঝে এটি বন্ধ করে রাখতে সক্ষম হতে চাই CtrlC

এবং আমি এমনভাবে এটি করতে চাই যা কেবল কোডে যুক্ত হয় (সুতরাং আমি বিদ্যমান আচরণকে প্রভাবিত করি না, বা রানের মাঝামাঝি সময়ে ধরা পড়ে যাওয়া ব্যতিক্রমটি মিস করি না))

[ CtrlCহ'ল সিগিন্ট বা সিস্টেমএক্সিট, যা SignalException.new("INT")রুবির ব্যতিক্রম হ্যান্ডলিং সিস্টেমের সমতুল্য বলে মনে হয় । class SignalException < Exception, যে কারণে এই সমস্যাটি উঠে আসে]]

আমি যে কোডটি লিখতে চাই তা হ'ল:

begin
  #dosomething
rescue SignalException => e
  raise e
rescue Exception => e
  #halt the exception's progress
end

সম্পাদনা: এই কোডটি ততক্ষণ কাজ করে, যতক্ষণ আপনি সঠিকভাবে ফাঁদে যেতে চান ব্যতিক্রমের ক্লাস পান। এটি সিস্টেমেক্সট, বিঘ্নিত বা আইআরবি :: নীচে হিসাবে বাতিল করা উচিত।

উত্তর:


132

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

আপনি যেখানেই পারেন, পরিবর্তন করুন

rescue Exception => e
  # ...
end

প্রতি

rescue StandardError => e
  # ...
end

যাদের আপনি স্ট্যান্ডার্ডআরারে পরিবর্তন করতে পারবেন না তাদের ব্যতিক্রমটি আবার উত্থাপন করুন:

rescue Exception => e
  # ...
  raise
end

বা, খুব কমপক্ষে, পুনরায় উত্থাপন করুন সিস্টেমএক্সিট এবং বিঘ্নিত

rescue SystemExit, Interrupt
  raise
rescue Exception => e
  #...
end

আপনার করা কোনও কাস্টম ব্যতিক্রম স্ট্যান্ডার্ডেরর থেকে নেওয়া উচিত , ব্যতিক্রম নয় ।


1
ওয়েইন, আপনি কি আইআরবি যুক্ত করতে এত দয়াবান হবেন: আপনার তালিকায়ও উদাহরণটি বাতিল করতে হবে?
টিম স্নোহাইট

1
@ টিম, আইআরবি.আরবি (আমার সিস্টেমে এটি /usr/lib/ruby/1.8/irb.rb তে) সন্ধান করুন এবং মূল লুপটি (@ প্রসঙ্গের অনুসন্ধান করুন) আবিষ্কার করুন। রেসকিউ ক্লজটি দেখুন এবং আমি মনে করি আপনি বুঝতে পারবেন কেন আইআরবি এটির মতো আচরণ করে।
ওয়েইন কনরাড

ধন্যবাদ. আইআরবি.আরবিতে # সিগন্যাল_হ্যান্ডেলের সংজ্ঞাটি দেখে আমার বুঝতেও সহায়তা করেছে। মূল লুপের ব্যতিক্রম ভেরিয়েবল বাঁধাইয়ের মধ্যে তাদের একটি ঝরঝরে কৌশল রয়েছে। (একটি নির্দিষ্ট ব্যতিক্রম বাছাই করার উপায় হিসাবে উদ্ধার শর্তগুলি ব্যবহার করে উদ্ধারকারী সংস্থাগুলির বাইরে সেই ব্যতিক্রমটি ব্যবহার করুন))
টিম স্নোহাইট

এগুলি নিখুঁত কাজ করে:rescue SystemExit, Interrupt raise rescue Exception => e
জেমস টান

73

আপনি যদি আপনার পুরো প্রোগ্রামটি মোড়ানো করতে পারেন তবে নীচের মতো কিছু করতে পারেন:

 trap("SIGINT") { throw :ctrl_c }

 catch :ctrl_c do
 begin
    sleep(10)
 rescue Exception
    puts "Not printed"
 end
 end

এটির মূলত CtrlCব্যতিক্রম হ্যান্ডলিংয়ের পরিবর্তে ক্যাচ / থ্রো ব্যবহার রয়েছে, সুতরাং বিদ্যমান কোডটিতে ইতিমধ্যে যদি একটি ক্যাচ থাকে: ctrl_c না থাকে তবে তা ঠিক করা উচিত।

বিকল্পভাবে আপনি একটি করতে পারেন trap("SIGINT") { exit! }exit!তাত্ক্ষণিকভাবে প্রস্থান করে, এটি কোনও ব্যতিক্রম বাড়ে না তাই কোডটি দুর্ঘটনাক্রমে এটি ধরতে পারে না।


2
দ্রষ্টব্য যে আইআরবিতে থাকা সিটিআরএল-সি আইআরবি :: বিসতৃত করে, স্বাক্ষর করে না। অন্যথায় @ লোগানের উত্তরটি একটি সমাধান।
টিম স্নোহাইট

1
রুবি ইন্টারপ্রেটারের জন্য টিমসনোহাইট SIGINTআমার পক্ষে ভাল কাজ করে।
ডিফ্ল্ট করুন

1
থ্রোক এবং ক্যাচ একই থ্রেডে থাকতে হবে, সুতরাং যদি আপনি অন্য থ্রেডে বাধা ব্যতিক্রমটি ধরতে চান তবে এটি কাজ করবে না।
ম্যাট কনোলি

39

আপনি যদি নিজের পুরো অ্যাপ্লিকেশনটিকে একটি begin ... rescueব্লকে (যেমন, থোর) মুড়ে রাখতে না পারেন তবে আপনি কেবল আটকাতে পারেন SIGINT:

trap "SIGINT" do
  puts "Exiting"
  exit 130
end

130 একটি স্ট্যান্ডার্ড প্রস্থান কোড।


1
FYI, 130 হ'ল সিটিআরএল-সি বিঘ্নিত স্ক্রিপ্টগুলির সঠিক প্রস্থান কোড: google.com/search?q=130+exit+code&en= ( 130 | Script terminated by Control-C | Ctl-C | Control-C is fatal error signal 2, (130 = 128 + 2, see above))
ডোরিয়ান

পারফেক্ট! আমার ক্রমাগত চলমান ব্যাকগ্রাউন্ড থ্রেড সহ একটি সিনকিট্রা সার্ভার রয়েছে এবং এটি অন্যথায় আচরণ পরিবর্তন না করে একটি থ্রেডটি পাশাপাশি একটি সেন্ট্রল-সিতে মারতে হবে বলে মনে হচ্ছে।
নার্ফানেটর

4

আমি ensureদুর্দান্ত প্রভাব ফেলছি! এটি এমন জিনিসগুলির জন্য যা আপনার জিনিসগুলি কেন শেষ হয় তা শেষ না করেই ঘটতে চান।


0

রুবিতে জিরোমিকিউ উপায়ে পরিষ্কারভাবে Ctrl-C পরিচালনা করা :

#!/usr/bin/env ruby

# Shows how to handle Ctrl-C
require 'ffi-rzmq'

context = ZMQ::Context.new(1)
socket = context.socket(ZMQ::REP)
socket.bind("tcp://*:5558")

trap("INT") { puts "Shutting down."; socket.close; context.terminate; exit}

puts "Starting up"

while true do
  message = socket.recv_string
  puts "Message: #{message.inspect}"
  socket.send_string("Message received")
end

উৎস


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