প্রদত্ত পিআইডি চলছে কিনা তা আমি কীভাবে পরীক্ষা করব?


16

আমি একটি পার্ল স্ক্রিপ্ট লিখছি যা পিআইডি সংগ্রহ করার জন্য লগফিলগুলি পার্স করে এবং তারপরে সেই পিআইডি চলছে কিনা তা পরীক্ষা করে। আমি এই চেকটি করার সর্বোত্তম উপায় সম্পর্কে চিন্তা করার চেষ্টা করছি। স্পষ্টতই, আমি এরকম কিছু করতে পারি:

system("ps $pid > /dev/null") && print "Not running\n";

তবে, আমি যদি সম্ভব হয় তবে সিস্টেম কলটি এড়াতে পছন্দ করব। তাই আমি ভেবেছিলাম আমি /procফাইল সিস্টেমটি ব্যবহার করতে পারি (বহনযোগ্যতা কোনও উদ্বেগ নয়, এটি সর্বদা লিনাক্স সিস্টেমে চলতে থাকবে) running উদাহরণ স্বরূপ:

if(! -d "/proc/$pid"){
    print "Not running\n";
}

এটা কি নিরাপদ? আমি কি সবসময় অনুমান করতে পারি যে যদি কোনও /proc/$pid/ডিরেক্টরি না থাকে তবে সম্পর্কিত পিআইডি চলছে না? আমি আশা করি যেহেতু এএফাইক psনিজে /procযেভাবেই এর তথ্য পায় তবে যেহেতু এটি প্রোডাকশন কোডের জন্য তাই আমি নিশ্চিত হতে চাই।

সুতরাং, এমন কোনও ঘটনা ঘটতে পারে যেখানে চলমান প্রক্রিয়াটির কোনও /proc/PIDডিরেক্টরি নেই বা যেখানে একটি /proc/PIDডিরেক্টরি বিদ্যমান এবং প্রক্রিয়াটি চলছে না? psডিরেক্টরিটির অস্তিত্ব পরীক্ষা করার জন্য পার্সিং পছন্দ করার কোনও কারণ আছে কি ?


2
killসিগন্যাল 0 ব্যবহার করে পার্ল ফাংশনটিও রয়েছে যা কোনও হত্যাকাণ্ড করে না তবে বলে যদি আপনি এটি করতে পারতেন (যেমন আপনার সেই প্রক্রিয়াটি সংকেত করার অনুমতি প্রয়োজন) need
meuh

1
'/ proc / $ PID' ঠিকঠাক হওয়া উচিত যদি আপনি লিনাক্সে এটি করছেন।
জুলাই'র মত

7
@ স্টারডন নোট করুন যে আপনি যে পদ্ধতিটি ব্যবহার করেন (এবং kill -0এটি সেরা) এটি কেবল আপনাকে জানায় যে প্রদত্ত পিআইডি সহ কোনও চলমান প্রক্রিয়া রয়েছে কিনা । প্রক্রিয়াটি এখনও এক মিলি সেকেন্ড পরে চলবে কিনা তা আপনাকে জানায় না, এবং এটি আপনাকে জানায় না যে প্রক্রিয়াটি আপনার আগ্রহী বা একটি সম্পর্কযুক্ত প্রক্রিয়া যা আকর্ষণীয় প্রক্রিয়াটি মারা যাওয়ার পরে একই পিআইডি বরাদ্দ করেছে কিনা তা আপনাকে জানায় না whether । প্রদত্ত পিআইডি চলছে কিনা তা পরীক্ষা করা প্রায় সবসময়ই ভুল : খুব কম পরিস্থিতি রয়েছে যেখানে এটি জাতি শর্তে প্রবণ নয়।
গিলস 'অশুভ হওয়া বন্ধ করুন'

1
@ গিলস আসলে, আমারও প্রক্রিয়াটির নামটি পরীক্ষা করা উচিত। যাইহোক, এই ক্ষেত্রে, পরে কোনও মিলসেকেন্ডে স্থিতি পরিবর্তন হয়েছে কিনা তা আমি বিবেচনা করি না। আমার ডিবিতে সক্রিয় হিসাবে পিডস এবং একটি ফাইল সম্পর্কিত সক্রিয় তালিকা রয়েছে। আমাকে কেবল এটি যাচাই করতে হবে যে ডিবি যে কিছু চালাচ্ছে তা আসলে চলছে না এবং সেটআপের উপর পর্যাপ্ত নিয়ন্ত্রণ রয়েছে তা জানতে যে এটি এলোমেলোভাবে আবার শুরু করতে পারে না।
টেরডন

3
@ মিকএলএইচ ওয়া, এটা আমাকে বলেছে। আপনি যদি এত খারাপ এবং বিপজ্জনক তা ব্যাখ্যা করার জন্য বিরক্ত করে থাকেন তবে এটি আপনার নিজস্ব প্রতিভা উদযাপনের পরিবর্তে একটি দরকারী মন্তব্য হতে পারে। আমি সত্যই সন্দেহ করি না, আমি কখনই প্রোগ্রামার হওয়ার দাবি করিনি, এজন্যই আমি প্রশ্নটি জিজ্ঞাসা করেছি, তবে আপনি উভয়ই অবমাননাকর এবং অপ্রয়োজনীয় হতে পেরেছেন।
টেরডন

উত্তর:


20

পার্ল ফাংশন kill(0,$pid) ব্যবহার করা যেতে পারে।

যদি রিটার্ন কোডটি 1 হয় তবে পিআইডি বিদ্যমান এবং আপনাকে এটিতে একটি সংকেত প্রেরণের অনুমতি দেওয়া হবে।

যদি রিটার্ন কোড 0 হয় তবে আপনার check! পরীক্ষা করা দরকার। এটি EPERM (অনুমতি অস্বীকৃত) হতে পারে যার অর্থ প্রক্রিয়াটি বিদ্যমান বা ESRCH যার ক্ষেত্রে প্রক্রিয়াটি বিদ্যমান নেই।

যদি আপনার চেকিং কোডটি চলমান থাকে root তবে আপনি খুনের রিটার্ন কোডটি পরীক্ষা করে এটি সহজ করতে পারেন; 0 => ত্রুটি, 1 => ঠিক আছে

উদাহরণ স্বরূপ:

% perl -d -e 0

Loading DB routines from perl5db.pl version 1.37
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

main::(-e:1):   0
  DB<1> print kill(0,500)
0
  DB<2> print $!
No such process
  DB<3> print kill(0,1)
0
  DB<4> print $!
Operation not permitted
  DB<5> print kill(0,$$)
1

এটি একটি সাধারণ ফাংশন তৈরি করা যেতে পারে

use Errno;

sub test_pid($)
{
  my ($pid)=@_;

  my $not_present=(!kill(0,$pid) && $! == Errno::ESRCH);

  return($not_present);
}

print "PID 500 not present\n" if test_pid(500);
print "PID 1 not present\n" if test_pid(1);
print "PID $$ not present\n" if test_pid($$);

এফডাব্লুআইডাব্লু, আপনি কীভাবে এটি করতে পারেন তা দেখিয়ে আমি একটি সাধারণ ফাংশন যুক্ত করেছি।
স্টিফেন হ্যারিস

হ্যাঁ, আমি মনে করি আমি এই সাথে যাব। আমি আমার মন্তব্য মুছে ফেলেছি যেহেতু আমি বুঝতে পেরেছিলাম যে আমার যা যা প্রয়োজন তা হ'ল if (!kill(0,$pid) && $! =~ /No such process/){ exit; }বা একই রকম। আমি আপনার Errnoসমাধানটি আরও ভাল পছন্দ করি , ধন্যবাদ। আমি সম্ভবত এটির সাথে যাব, আমি অন্তর্নিহিত লিনাক্স প্রশ্নের যে কেউ উত্তর দিতে পারে সে ক্ষেত্রে আমি কিছুক্ষণ অপেক্ষা করব।
টেরডন

2
যদি /procমাউন্ট করা থাকে তবে নেমস্পেসে দৃশ্যমান প্রতিটি পিআইডি উপস্থিত থাকবে, সুতরাং আপনার -d /proc/$pidপরীক্ষাটি কার্যকর হবে ... তবে এর মধ্যে নেটিভ সিস্টেম কল ব্যবহার না করে ফাইল সিস্টেমে যাওয়া অন্তর্ভুক্ত।
স্টিফেন হ্যারিস

হ্যাঁ, যা আমি এড়াতে চেয়েছিলাম তা হ'ল।
টেরডন

2
@ ইটারডন: আমি বুঝতে পেরেছি যে আমার বিভ্রান্তি এ থেকে এসেছিল যে "সিস্টেম কল" দ্বারা আপনি আসলে " systemকল" - অর্থাত্ systemফাংশনে নিজেই একটি কল করেছিলেন , "সিস্টেম কল" নয় । পরেরটি আপনি এড়াতে পারবেন না তবে পূর্বেরটি অবশ্যই আপনি পারেন। বুদ্ধি এখন!
ব্যবহারকারী541686

6
  • আমি 99.9% নিশ্চিত করুন যে কিনা তা পরীক্ষা করে আছি বিদ্যমান (এবং ডিরেক্টরির হয়) যেমন নির্ভরযোগ্য হিসাবে 98% হল টেকনিক। 98% 100% না হওয়ার কারণটি স্টিফেন হ্যারিস একটি মন্তব্যে স্পর্শ করেছিলেন (এবং বাউসন করেছেন) - সম্ভবত , ফাইল সিস্টেমটি মাউন্ট করা যায় না। এটা দাবি করতে বৈধ হতে পারে যে একটি Linux সিস্টেম ছাড়া একটি ক্ষতিগ্রস্ত, নিকৃষ্ট সিস্টেম - সব পরে, কিছু পছন্দ , এবং/proc/PIDkill 0/proc/procpstoplsof সম্ভবত কাজ করে না - এবং তাই এই শক্তি একটি প্রকাশনা সিস্টেমের জন্য একটি বিষয় না। তবে এটি (তাত্ত্বিকভাবে) সম্ভব যে এটি কখনই মাউন্ট করা হয়নি (যদিও এটি সিস্টেমটিকে একটি সাধারণ অবস্থায় আসতে বাধা দিতে পারে) তবে এটি আনমাউন্ট করা অবশ্যই সম্ভব (আমি এটি পরীক্ষা করেছি 1)), এবং আমি বিশ্বাস করি যে এটির কোন গ্যারান্টি নেই (যেমন, এটি পসিক্স দ্বারা আবশ্যক নয়)। এবং, যতক্ষণ না সিস্টেমটি পুরোপুরি হোসড হয়, killকাজ করবে।
  • স্টিফেনের মন্তব্যে "ফাইল সিস্টেমে বাইরে যাওয়া" এবং "নেটিভ সিস্টেম কল ব্যবহার করা" সম্পর্কে আলোচনা করা হয়েছে। আমি বিশ্বাস করি এটি বেশিরভাগ ক্ষেত্রেই একটি লাল রঙের হেরিং।
    • হ্যাঁ, অ্যাক্সেস করতে কোনো চেষ্টা /proc রুট ডিরেক্টরিটি পড়া প্রয়োজন খুঁজে/proc ফাইলসিস্টেম। এই সত্য কোনো প্রয়াস অ্যাক্সেস করার জন্য কোনো কিছু সহ, একটি পরম পথনাম দ্বারা ফাইল /bin, /etcএবং /dev। এটি প্রায়শই ঘটে থাকে যে রুট ডিরেক্টরিটি অবশ্যই সিস্টেমের পুরো আজীবন (আপটাইম) স্মরণে রাখা হয়, সুতরাং এই ধাপটি কোনও ডিস্ক I / O ছাড়াই করা যায়। এবং একবার আপনার ইনোড হয়ে গেলে /proc, যা কিছু ঘটে থাকে তা স্মৃতিতে।
    • আপনি কীভাবে অ্যাক্সেস করবেন /proc? সঙ্গে stat, open, readdir, ইত্যাদি নেটিভ সিস্টেম যতটা প্রত্যেক বিট আহ্বান যা kill
  • প্রশ্নটি একটি প্রক্রিয়া চলমান সম্পর্কে আলোচনা করে। এটি পিচ্ছিল বাক্য is যদি আপনি প্রকৃতপক্ষে প্রক্রিয়াটি চলছে কিনা তা পরীক্ষা করতে চান (যেমন, রান কাতারে; সম্ভবত কিছু সিপিইউতে বর্তমান প্রক্রিয়া; ঘুমাচ্ছেন না, অপেক্ষা করছেন না বা থামলেন না), আপনাকে একটি করতে হবে এবং আউটপুটটি পড়তে হবে বা দেখুন । তবে আমি আপনার প্রশ্ন বা মন্তব্যে কোনও ইঙ্গিত দেখতে পাচ্ছি না যে আপনি এটি নিয়ে উদ্বিগ্ন।ps PID /proc/PID/stat

    ঘরের হাতি, তবে, একটি জম্বি 2 প্রক্রিয়া জীবিত এবং ভাল যে প্রক্রিয়া থেকে পৃথক করা কঠিন হতে পারে।  kill 0একটি জম্বি উপর কাজ করে, এবং বিদ্যমান। আপনি পূর্ববর্তী অনুচ্ছেদে তালিকাভুক্ত কৌশলগুলি ( আউটপুটটি করা এবং পড়তে বা দেখছেন ) এর সাহায্যে জম্বিগুলি সনাক্ত করতে পারেন । আমার খুব দ্রুত ও নৈমিত্তিক (অর্থাত, খুব পুঙ্খানুপুঙ্খ নয়) পরীক্ষামূলক প্রস্তাব দেওয়া এছাড়াও আপনি একটি করে এটা করতে পারেন যে বা উপর , অথবা - এই বোকচন্দর উপর ব্যর্থ হবে। (তবে, আপনার নিজস্ব নয় এমন প্রক্রিয়াগুলিতেও তারা ব্যর্থ হবে))/proc/PIDps PID/proc/PID/statreadlinklstat/proc/PID/cwd/proc/PID/root/proc/PID/exe

____________
1  যদি -f( f orce) বিকল্পটি কাজ না করে, চেষ্টা করুন -l( l azy)।
2  অর্থাত্, একটি প্রক্রিয়া যা প্রস্থান / মারা / অবসান হয়েছে, তবে যার পিতামাতা এখনও করেন নি একটি wait


আমার উত্তর সম্পর্কে আপনার মন্তব্যের জন্য ধন্যবাদ, যা আমি মুছে ফেলেছি কারণ এটি ভুল ছিল। আমি বিশ্বাস করি না যে kill(2)ম্যানপেজটি আপনার নির্দেশিত আচরণটি সরাসরি নির্দেশ করে, তবে perlfuncম্যানপেজটি করে। আমি মাইকেল কেরিস্ককে ইমেল করবো সিস্টেম ম্যানপেজ সম্পর্কে তার কী মন্তব্য আছে তা দেখার জন্য।
jrw32982 মনিকা

আমি kill(2)"সিগন্যাল 0." পাঠানোর অনুমতি সংক্রান্ত ম্যান-পৃষ্ঠাটি স্পষ্ট করার জন্য একটি বাগ রিপোর্ট দায়ের করেছি
jrw32982 মনিকা

@ jrw32982: ওয়েল, ম্যান পেজটি এই জাতীয় জিনিসগুলি বলেছে, " সিগ আর্গুমেন্টটি 0 হতে পারে , এক্ষেত্রে ত্রুটি পরীক্ষা করা হয় ..." এবং " ত্রুটি - কিল () সিস্টেম কল ব্যর্থ হবে এবং কোনও সংকেত প্রেরণ করা হবে না যদি: … প্রেরণ প্রক্রিয়াটি সুপার-ব্যবহারকারী নয় এবং এর কার্যকর ব্যবহারকারী আইডি গ্রহণের প্রক্রিয়াটির কার্যকর ব্যবহারকারী-আইডির সাথে মেলে না। … ”এখন আপনি এটি উল্লেখ করেছেন, আমি অনুমান করি যে এটির একাধিক উপায়ে ব্যাখ্যা করা যেতে পারে তবে আফসোসের বিষয়, অনেক ইউনিক্স ম্যান পৃষ্ঠাগুলি এই স্টাইলে লেখা হয়, আপনাকে লাইনের মাঝে পড়তে হবে। মাইকেল বিশ্বাস করতে পারে যে এটি যথেষ্ট হিসাবে পরিষ্কার।
জি-ম্যান

মাইকেল kill(2)ম্যানপেজে পরিবর্তন করেছে (আমি এটি অনলাইনে এখনও দেখছি না): "যদি সিগ 0 হয়, তবে কোনও সংকেত প্রেরণ করা হয় না, তবে অস্তিত্ব এবং অনুমতি চেকগুলি এখনও সঞ্চালিত হয়; এটি কোনও অস্তিত্বের জন্য পরীক্ষা করতে ব্যবহার করা যেতে পারে প্রক্রিয়া আইডি বা প্রক্রিয়া গ্রুপ আইডি যা কলকারীকে সংকেত দেওয়ার অনুমতি দেওয়া হয়। "
jrw32982
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.