কোন প্রক্রিয়াটি Ctrl + C দ্বারা বাতিল হয়ে যায় তা নিয়ন্ত্রণ করুন


13

আমার একটি লাইভ সিডি রয়েছে যা লিনাক্সে বুট হয় এবং একটি ছোট বাশ স্ক্রিপ্ট চালায়। স্ক্রিপ্টটি সন্ধান করে এবং একটি দ্বিতীয় প্রোগ্রাম চালায় (যা সাধারণত সংকলিত সি ++ বাইনারি হয়)।

আপনি Ctrl+ টিপে দ্বিতীয় প্রোগ্রামটি বাতিল করতে সক্ষম হবেন বলে মনে করা হচ্ছে C। যা হওয়া উচিত তা হ'ল দ্বিতীয় প্রোগ্রামটি থেমে আছে এবং বাশ স্ক্রিপ্টটি ক্লিনআপ চালিয়ে যাচ্ছে। কি আসলে ঘটবে উভয় প্রধান আবেদন এবং ব্যাশ স্ক্রিপ্ট অবসান ঘটবে। যা কোন সমস্যা।

সুতরাং আমি trapবিল্টিনকে ব্যাগকে SIGINT এড়ানোর জন্য বলার জন্য ব্যবহার করেছি । এবং এখন Ctrl+ Cসি ++ অ্যাপ্লিকেশনটি সমাপ্ত করে, তবে বাশ এটি চালিয়ে যায়। গ্রেট।

ওহ হ্যাঁ ... কখনও কখনও "দ্বিতীয় অ্যাপ্লিকেশন" হ'ল আরেকটি বাশ স্ক্রিপ্ট। আর এ যে মামলা, Ctrl+ + Cএখন নেই কিছুই সবটা

পরিষ্কারভাবে এই জিনিসগুলি কীভাবে কাজ করে তা সম্পর্কে আমার বোঝা ভুল ... ব্যবহারকারী Ctrl+ চাপলে কোন প্রক্রিয়াটি SIGINT পায় আমি কীভাবে তা নিয়ন্ত্রণ করব C? আমি এই সংকেতটি কেবল একটি নির্দিষ্ট প্রক্রিয়াতে পরিচালনা করতে চাই ।

উত্তর:


11

অনেক পরে, বহু ঘন্টা ইন্টারনেটে মুখ সন্ধান করার পরে, আমি উত্তর খুঁজে পেয়েছি।

  1. লিনাক্স একটি প্রক্রিয়া গ্রুপ ধারণা আছে ।

  2. টিটিওয়াই ড্রাইভারটির অগ্রভাগ প্রক্রিয়া গ্রুপের ধারণা রয়েছে।

  3. যখন আপনি টিপুন Ctrl+ + C, পির TTY পাঠায় SIGINTকরার যে প্রক্রিয়া ফোরগ্রাউন্ড প্রক্রিয়া গোষ্ঠীতে। ( এই ব্লগ এন্ট্রি এছাড়াও দেখুন ।)

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

সমাধানটি এখন সুস্পষ্ট: আমাদের একটি নতুন প্রক্রিয়া গ্রুপে অ্যাপ্লিকেশনটি তৈরি করা দরকার, এবং এটি এই টিটিওয়াইয়ের জন্য অগ্রভাগ প্রক্রিয়া গোষ্ঠী করা উচিত। স্পষ্টতই এটি করার আদেশ

setsid -c <applcation>

এবং এটি সব। এখন যখন ব্যবহারকারী Ctrl+ Cটিপেন, সাইন্ট অ্যাপ্লিকেশনটিতে (এবং এটির যে কোনও শিশু থাকতে পারে) এবং অন্য কেউ পাঠানো হবে। যা আমি চেয়েছিলাম।

  • setsid নিজেই অ্যাপ্লিকেশনটিকে একটি নতুন প্রক্রিয়া গোষ্ঠীতে রাখে (প্রকৃতপক্ষে একটি সম্পূর্ণ নতুন "সেশন", যা দৃশ্যত প্রক্রিয়া গ্রুপের একটি গ্রুপ)।

  • -cপতাকা যুক্ত করা এই নতুন প্রক্রিয়া গোষ্ঠীকে বর্তমান টিটিওয়াইয়ের জন্য "অগ্রভাগ" প্রক্রিয়া গ্রুপে পরিণত করে। (অর্থাৎ SIGINTআপনি Ctrl+ টিপলে এটি পাওয়া যায় C)

বাশ কখন নতুন প্রক্রিয়া গোষ্ঠীতে প্রক্রিয়া চালায় না বা চালায় না সে সম্পর্কে আমি প্রচুর বিরোধী তথ্য দেখেছি। (বিশেষত, এটি "ইন্টারেক্টিভ" এবং "অ-ইন্টারেক্টিভ" শেলগুলির জন্য পৃথক বলে মনে হয়)) আমি পরামর্শগুলি দেখেছি যে আপনি সম্ভবত চালাক পাইপের কৌশলগুলির সাথে এটি কাজ করতে পারেন ... আমি জানি না। তবে উপরের পদ্ধতির বিষয়টি আমার পক্ষে কাজ করে বলে মনে হচ্ছে।


5
আপনি প্রায় পেয়ে গেছেন ... স্ক্রিপ্ট চলাকালীন চাকরি নিয়ন্ত্রণ ডিফল্টরূপে অক্ষম করা হয় তবে আপনি এটি দিয়ে সক্ষম করতে পারেন set -msetsidআপনি যতবার বাচ্চা চালান প্রতিবার ব্যবহার করার চেয়ে এটি কিছুটা পরিষ্কার এবং সহজ ।
psusi

টিপসটির জন্য ধন্যবাদ! আমার কেবল একটি শিশু চালানো দরকার, তাই এটি কোনও বড় কথা নয়। আমি এখন জানি বাশ ম্যানুয়ালটিতে কোথায় সন্ধান করা যায় ...
ম্যাথমেটিকালঅরকিড

হাস্যকরভাবে, আমার বিপরীত সমস্যা রয়েছে যেখানে আমি পিতামাতার সিগিন্ট ধরতে চাই, তবে এটি "চতুর পাইপ ট্রিক্রিয়ার কারণে" হয় না। এছাড়াও অগ্রগতি গোষ্ঠী -> প্রক্রিয়া দল
অ্যান্ড্রু ডোমাসেক

2

আমি f01-এ মন্তব্যে যেমন উল্লেখ করেছি, আপনার বাচ্চাদের প্রক্রিয়াতে SIGTERM প্রেরণ করা উচিত। এখানে বেশ কয়েকটি স্ক্রিপ্ট রয়েছে যা দেখায় যে কীভাবে সি tra সি ফাঁদ করা যায় এবং একটি শিশু প্রক্রিয়াতে সংকেত প্রেরণ করা যায়।

প্রথম, পিতামাতা।

traptest

#!/bin/bash

# trap test
# Written by PM 2Ring 2014.10.23

myname=$(basename "$0")
child=sleeploop

set_trap()
{
    sig=$1
    msg="echo -e \"\n$myname received ^C, sending $sig to $child, $pid\""
    trap "$msg; kill -s $sig $pid" SIGINT
}
trap "echo \"bye from $myname\"" EXIT

echo "running $child..."
./$child 5  &
pid=$!

# set_trap SIGINT
set_trap SIGTERM
echo "$child pid = $pid"

wait $pid
echo "$myname finished waiting"

এবং এখন, শিশু।

sleeploop

#!/bin/bash

# child script for traptest
# Written by PM 2Ring 2014.10.23

myname=$(basename "$0")
delay="$1"

set_trap()
{
    sig=$1
    trap "echo -e '\n$myname received $sig signal';exit 0" $sig
}

trap "echo \"bye from $myname\"" EXIT
set_trap SIGTERM
set_trap SIGINT

#Select sleep mode
if false
then
    echo "Using foreground sleep"
    Sleep()
    {
        sleep $delay
    }
else
    echo "Using background sleep"
    Sleep()
    {
        sleep "$delay" &
        wait $!
    }
fi

#Time to snooze :)
for ((i=0; i<5; i++));
do
    echo "$i: sleeping for $delay"
    Sleep
done

echo "$myname terminated normally"

যদি ট্র্যাপেস্ট প্রেরণ করে সিগন্যারম জিনিসগুলি ভাল আচরণ করে তবে ট্র্যাপেস্টেস্ট যদি স্বাক্ষর প্রেরণ করে তবে স্লিপলুপ কখনই এটি দেখে না।

যদি স্লিপলুপ সিগনটারটিকে ফাঁদে ফেলে এবং স্লিপ মোডটি অগ্রভাগ হয়, তবে বর্তমান ঘুম থেকে জাগ্রত না হওয়া অবধি এটি সিগন্যালের প্রতিক্রিয়া জানাতে পারে না। তবে যদি স্লিপ মোড ব্যাকগ্রাউন্ড হয় তবে তা অবিলম্বে প্রতিক্রিয়া জানাবে।


এই দুর্দান্ত উদাহরণের জন্য আপনাকে ধন্যবাদ, আমি কীভাবে আমার স্ক্রিপ্টটি উন্নত করতে পারি তা বোঝার জন্য এটি আমাকে অনেক সহায়তা করেছে :)
TabeaKischka

2

আপনার দীক্ষিত বাশ স্ক্রিপ্টে।

  • দ্বিতীয় প্রোগ্রামের পিআইডি ট্র্যাক রাখুন

  • সাইন ইন ধরুন

  • আপনি যখন একটি সাইন ইন করেছেন, তখন দ্বিতীয় প্রোগ্রাম পিআইডি-তে একটি সাইন ইন প্রেরণ করুন


1
এটি সাহায্য নাও করতে পারে। আপনি যদি অভিভাবক স্ক্রিপ্টে স্বাক্ষরটি ফাঁদে ফেলে থাকেন তবে শিশু স্ক্রিপ্টগুলি আপনি বাবা-মায়ের কাছ থেকে বা অন্য কোনও শেল থেকে প্রেরণ করে সাইন ইন করতে পারবেন না। তবে এটি যতটা শোনাচ্ছে ততটা খারাপ নয়, কারণ আপনি বাচ্চাকে সাইনটারম প্রেরণ করতে পারেন, এটি সম্ভবত ব্যবহারের জন্য পছন্দসই সংকেত।
প্রধানমন্ত্রী 2 রিং

1
কেন সাইনটারম "পছন্দসই"?
গাণিতিক

তারা প্রায় অনুরূপ। সিগিন্ট হ'ল নিয়ন্ত্রণকারী টার্মিনাল / ব্যবহারকারীর দ্বারা প্রেরিত সিগন্যাল যেমন Ctrl + C। আপনি যদি প্রক্রিয়াটি শেষ করতে চান তবে সিগন্টরও আপনি যা প্রেরণ করতে পারেন। এখানে আরো চিন্তা en.wikipedia.org/wiki/Unix_signal
F01
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.