প্রকৃত ব্যবহারের জন্য, আপনার শীর্ষ ভোট দেওয়া উত্তর ব্যবহার করা উচিত ।
যাইহোক, আমি কিছু ভাঙ্গা এবং অর্ধ-কার্যক্ষম ps
ব্যবহারগুলি এবং তাদের থাকা বহু সতর্কতাগুলি নিয়ে আলোচনা করতে চাই , যেহেতু আমি লোকদের সেগুলি ব্যবহার করতে দেখছি।
এই উত্তরটি আসলে " শেলটিতে লকিং ব্যবহার ps
ও grep
পরিচালনা করার জন্য কেন নয় ?" এর উত্তর
ভাঙা পন্থা # 1
প্রথমত, অন্য উত্তরে প্রদত্ত একটি পদ্ধতির যে এটি কার্যকর করে না (এবং কখনই পারে না) এবং পরিষ্কারভাবে কখনও পরীক্ষা করা হয়নি এমন সত্ত্বেও কয়েকটি উত্সাহ রয়েছে:
running_proc=$(ps -C bash -o pid=,cmd= | grep my_script);
if [[ "$running_proc" != "$$ bash my_script" ]]; do
echo Already locked
exit 6
fi
আসুন সিনট্যাক্স ত্রুটিগুলি এবং ভাঙ্গা ps
যুক্তিগুলি ঠিক করুন এবং পান:
running_proc=$(ps -C bash -o pid,cmd | grep "$0");
echo "$running_proc"
if [[ "$running_proc" != "$$ bash $0" ]]; then
echo Already locked
exit 6
fi
এই স্ক্রিপ্টটি সর্বদা 6 থেকে প্রস্থান করা হবে , আপনি এটি যেভাবে চালান তা বিবেচনা করেই।
আপনি যদি এটির সাথে চালনা করেন ./myscript
তবে ps
আউটপুটটি ঠিক এটি হবে 12345 -bash
যা প্রয়োজনীয় স্ট্রিংয়ের সাথে মেলে না 12345 bash ./myscript
, তাই এটি ব্যর্থ হবে।
আপনি যদি এটির সাথে চালনা করেন তবে bash myscript
জিনিসগুলি আরও আকর্ষণীয় হয়ে উঠবে। বাশ প্রক্রিয়াটি পাইপলাইনটি চালানোর জন্য কাঁটাচামচ করে, এবং শিশু শেলটি ps
এবং চালায় grep
। আসল শেল এবং চাইল্ড শেল উভয়ই ps
আউটপুটটিতে প্রদর্শিত হবে, এরকম কিছু:
25793 bash myscript
25795 bash myscript
এটি প্রত্যাশিত আউটপুট নয় $$ bash $0
, সুতরাং আপনার স্ক্রিপ্টটি প্রস্থান করবে।
ভাঙা পন্থা # 2
ভাঙা পদ্ধতির # 1 লিখেছেন এমন ব্যবহারকারীদের কাছে এখন সমস্ত ন্যায্যতার সাথে আমি যখন প্রথম চেষ্টা করেছি তখন আমি নিজেই অনুরূপ কিছু করেছি:
if otherpids="$(pgrep -f "$0" | grep -vFx "$$")" ; then
echo >&2 "There are other copies of the script running; exiting."
ps >&2 -fq "${otherpids//$'\n'/ }" # -q takes about a tenth the time as -p
exit 1
fi
এটি প্রায় কাজ করে। তবে পাইপটি চালানোর জন্য দৃking়তার বিষয়টি এটিকে ছুঁড়ে দেয়। সুতরাং এই এক সর্বদা প্রস্থান করবে, এছাড়াও।
অবিশ্বাস্য পদ্ধতির # 3
pids_this_script="$(pgrep -f "$0")"
if not_this_process="$(echo "$pids_this_script" | grep -vFx "$$")"; then
echo >&2 "There are other copies of this script running; exiting."
ps -fq "${not_this_process//$'\n'/ }"
exit 1
fi
এই সংস্করণটি প্রথমে তাদের কমান্ড লাইন আর্গুমেন্টে সমস্ত স্ক্রিপ্ট রয়েছে এমন সমস্ত পিআইডি পেয়ে, এবং তারপরে বর্তমান স্ক্রিপ্টের পিআইডি বাদ দিতে পৃথকভাবে সেই পিডলিস্টটি ফিল্টার করে # 2 পদ্ধতির ক্ষেত্রে পাইপলাইন কাঁটাচামানের সমস্যাটিকে এড়িয়ে চলে ।
এটি কার্যকর হতে পারে ... অন্য কোনও প্রক্রিয়া সরবরাহের সাথে কমান্ড লাইনটি মিলছে না $0
, এবং স্ক্রিপ্ট সরবরাহ করার ক্ষেত্রে সর্বদা একইভাবে বলা হয় (যেমন যদি এটি কোনও আপেক্ষিক পথ এবং তারপরে একটি পরম পথের সাথে ডাকা হয়, তবে পরবর্তী উদাহরণটি পূর্ববর্তীটি লক্ষ্য করবে না )।
অবিশ্বাস্য পদ্ধতি # 4
সুতরাং যদি আমরা সম্পূর্ণ কমান্ড লাইনটি পরীক্ষা করা ছেড়ে চলে যাই, যেহেতু এটি সম্ভবত কোনও স্ক্রিপ্ট নির্দেশ করে না, এবং lsof
এই স্ক্রিপ্টটি খোলা আছে এমন সমস্ত প্রক্রিয়াগুলি অনুসন্ধান করার জন্য এটি পরীক্ষা করে দেখুন?
ঠিক আছে, হ্যাঁ, এই পদ্ধতিরটি খুব খারাপ নয়:
if otherpids="$(lsof -t "$0" | grep -vFx "$$")"; then
echo >&2 "Error: There are other processes that have this script open - most likely other copies of the script running. Exiting to avoid conflicts."
ps >&2 -fq "${otherpids//$'\n'/ }"
exit 1
fi
অবশ্যই, যদি স্ক্রিপ্টের অনুলিপিটি চলমান থাকে, তবে নতুন উদাহরণটি ঠিক ঠিক শুরু হবে এবং আপনার দুটি কপি চলবে।
অথবা যদি চলমান স্ক্রিপ্টটি সংশোধন করা হয় (যেমন ভিমের সাথে বা একটি সহ git checkout
), তবে স্ক্রিপ্টের "নতুন" সংস্করণটি কোনও সমস্যা ছাড়াই শুরু হবে, যেহেতু ভিম এবং git checkout
ফলস্বরূপ উভয়ের পরিবর্তে একটি নতুন ফাইল (একটি নতুন ইনোড) তৈরি হবে পুরোনো একটি.
তবে, যদি স্ক্রিপ্টটি কখনও সংশোধন করা হয় না এবং কখনও অনুলিপি করা হয় না, তবে এই সংস্করণটি বেশ ভাল। কোনও রেসের শর্ত নেই কারণ স্ক্রিপ্ট ফাইলটি চেক পৌঁছানোর আগেই খোলা থাকতে হবে।
অন্য কোনও প্রক্রিয়াটির স্ক্রিপ্ট ফাইল খোলা থাকলেও এখনও মিথ্যা ইতিবাচক থাকতে পারে, তবে নোট করুন যে এটি ভিমে সম্পাদনা করার জন্য উন্মুক্ত থাকলেও, ভিএম আসলে স্ক্রিপ্ট ফাইলটি উন্মুক্ত রাখে না ফলস্বরূপ মিথ্যা ধনাত্মকতার ফল হবে না।
তবে মনে রাখবেন, স্ক্রিপ্টটি সম্পাদনা করা বা অনুলিপি করা হতে পারে যদি আপনি মিথ্যা নেতিবাচক অর্থাত একাধিক দৃষ্টান্ত একসাথে চলতে পারেন তবে এই পদ্ধতির ব্যবহার করবেন না - সুতরাং ভিমের সাথে সম্পাদনা মিথ্যা ধনাত্মক ধরণের ধরণের দেয় না এই বিষয়টি সত্য নয় তোমাকে. আমি এটা উল্লেখ, যদিও কারণ পদ্ধতির # 3 করে মিথ্যা positives দিতে (অর্থাত শুরু করতে রাজি) যদি স্ক্রিপ্টটি তেজ সঙ্গে খোলা আছে।
তাহলে কি করব, তাহলে?
এই প্রশ্নের টপ ভোট উত্তর একটি ভাল কঠিন পদ্ধতির দেয়।
সম্ভবত আপনি আরও ভাল একটি লিখতে পারেন ... তবে উপরের সমস্ত পদ্ধতির সাথে যদি আপনি সমস্ত সমস্যা এবং সতর্কতা বুঝতে না পারেন তবে আপনি লকিং পদ্ধতিটি লিখে ফেলতে পারবেন না যা সেগুলি এড়িয়ে চলে।
kill
; এবং নিজের পিডটিকে কেবল স্পর্শ না করে লকফাইলে সংরক্ষণ করা ভাল অনুশীলন বলে মনে হয়।