Ctrl + C দিয়ে কোনও বাশ স্ক্রিপ্ট থামাতে অক্ষম


42

তারিখটি মুদ্রণের জন্য এবং একটি দূরবর্তী মেশিনে পিং করার জন্য আমি একটি লুপ সহ একটি সাধারণ বাশ স্ক্রিপ্ট লিখেছিলাম:

#!/bin/bash
while true; do
    #     *** DATE: Thu Sep 17 10:17:50 CEST 2015  ***
    echo -e "\n*** DATE:" `date` " ***";
    echo "********************************************"
    ping -c5 $1;
done

আমি যখন এটি টার্মিনাল থেকে চালিত করি তখন আমি এটিকে থামাতে সক্ষম হই না Ctrl+C। দেখে মনে হচ্ছে এটি ^Cটার্মিনালে প্রেরণ করে তবে স্ক্রিপ্টটি থামায় না।

MacAir:~ tomas$ ping-tester.bash www.google.com

*** DATE: Thu Sep 17 23:58:42 CEST 2015  ***
********************************************
PING www.google.com (216.58.211.228): 56 data bytes
64 bytes from 216.58.211.228: icmp_seq=0 ttl=55 time=39.195 ms
64 bytes from 216.58.211.228: icmp_seq=1 ttl=55 time=37.759 ms
^C                                                          <= That is Ctrl+C press
--- www.google.com ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 40.887/59.699/78.510/18.812 ms

*** DATE: Thu Sep 17 23:58:48 CEST 2015  ***
********************************************
PING www.google.com (216.58.211.196): 56 data bytes
64 bytes from 216.58.211.196: icmp_seq=0 ttl=55 time=37.460 ms
64 bytes from 216.58.211.196: icmp_seq=1 ttl=55 time=37.371 ms

আমি যতবার এটি চাপছি বা আমি কত দ্রুত এটি চাপছি না। আমি এটি থামাতে পারছি না।
পরীক্ষা করুন এবং নিজের দ্বারা উপলব্ধি করুন।

পার্শ্ব সমাধান হিসাবে, আমি এটি দিয়ে থামিয়ে দিচ্ছি Ctrl+Z, এটি এটিকে থামায় এবং তারপরে kill %1

এখানে ঠিক কী ঘটছে ^C?

উত্তর:


26

কি হবে যে উভয় bashএবং pingSIGINT পান ( bashহচ্ছে না ইন্টারেক্টিভ, উভয় pingএবং bashএকই প্রক্রিয়া গ্রুপ যা ইন্টারেক্টিভ শেল আপনার কাছ থেকে স্ক্রিপ্ট দৌড়ে দ্বারা তৈরি করা হয়েছে এবং সেট টার্মিনালের ফোরগ্রাউন্ড প্রক্রিয়া দল হিসেবে চালানোর)।

যাইহোক, bashবর্তমানে চলমান কমান্ডটি প্রস্থান হওয়ার পরে কেবলমাত্র অ্যাসিঙ্ক্রোনিকভাবে সাইন ইন করে পরিচালনা করে। bashকেবলমাত্র সইগিন্ট প্রাপ্তির পরে যদি বর্তমান চলমান কমান্ডটি একটি সাইন্টের (যেমন এর প্রস্থান স্থিতিটি ইঙ্গিত করে যে এটি স্বাক্ষর দ্বারা হত্যা করা হয়েছে) মারা যায়।

$ bash -c 'sh -c "trap exit\ 0 INT; sleep 10; :"; echo here'
^Chere

সর্বোপরি, bash, shএবং sleepSIGINT যখন আমি Ctrl-C, টিপুন, গ্রহণ কিন্তু shপ্রস্থানের 0 প্রস্থান কোড সহ স্বাভাবিকভাবে, তাই bashSIGINT উপেক্ষা করে, যার কারণে আমরা "এখানে" দেখুন।

ping, কমপক্ষে আইপুইটস থেকে একজন, এর মতো আচরণ করে। বাধা দেওয়া হলে, এটি পরিসংখ্যানগুলি মুদ্রণ করে এবং এর পিংস উত্তর দেওয়া হয়েছিল কিনা তার উপর নির্ভর করে 0 বা 1 প্রস্থান স্থিতি দিয়ে প্রস্থান করে। সুতরাং, যখন আপনি pingচলমান অবস্থায় Ctrl-C টিপুন , bashনোটগুলি নোট করে যে আপনি Ctrl-Cএর সিগিন্ট হ্যান্ডলারগুলিতে চাপ দিয়েছেন , তবে যেহেতু pingস্বাভাবিকভাবে প্রস্থান হয়, bashপ্রস্থান হয় না।

যদি আপনি sleep 1সেই লুপটিতে একটি জুড়েন এবং চলমান Ctrl-Cঅবস্থায় টিপুন sleep, কারণ sleepসাইন্টে কোনও বিশেষ হ্যান্ডলার নেই, তবে এটি মারা যাবে এবং রিপোর্ট করবে bashযে এটি একটি সাইন্টের কারণে মারা গেছে, এবং সেই ক্ষেত্রে bashপ্রস্থান করবে (এটি আসলে সাইন্টের সাহায্যে নিজেকে মেরে ফেলবে) বাধাকে তার পিতামাতার কাছে রিপোর্ট করতে)।

কেন bashএরকম আচরণ করে তা সম্পর্কে, আমি নিশ্চিত নই এবং আমি নোট করি যে আচরণটি সর্বদা নিরস্তকর নয়। আমি কেবল বিকাশ মেলিং তালিকায় প্রশ্নটিbash জিজ্ঞাসা করেছি ( আপডেট : @ জিলস এখন তার উত্তরে কারণটি পেরেক দিয়েছেন )।

আমি কেবলমাত্র অন্য শেলটি দেখতে পেলাম যে একইভাবে আচরণ করে তা হ'ল ksh93 (আপডেট, @ জিলিস দ্বারা উল্লিখিতsh , যেমন ফ্রিবিএসডিও করে )। সেখানে, SIGINT স্পষ্টভাবে উপেক্ষা করা হবে বলে মনে হচ্ছে। এবং ksh93যখনই একটি কমান্ড স্বাক্ষর দ্বারা নিহত হয় তখন উপস্থিত হয়।

আপনি bashউপরের মতো একই আচরণ পান তবে:

ksh -c 'sh -c "kill -INT \$\$"; echo test'

"পরীক্ষা" আউটপুট দেয় না। এটি হ'ল এটি সাইন্টের সাথে মারা যাওয়ার অপেক্ষায় থাকা কমান্ডটি স্বাক্ষর না করলেও (সাইন্টের সাথে নিজেকে মেরে সেখানে) বেরিয়ে যায়, এমনকি যদি তা নিজেই সেই সাইনটি না পায়।

চারপাশের কাজটি হ'ল একটি যুক্ত করা:

trap 'exit 130' INT

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

আদর্শভাবে, আমরা আমাদের পিতামাতাকে জানাতে চাই যে আমরা একটি স্বাক্ষরের কারণে মারা গিয়েছি (যাতে এটি অন্য কোনও স্ক্রিপ্ট হয় তবে bashসেই bashস্ক্রিপ্টটিও বাধাগ্রস্ত হয়)। একটি এরকম exit 130(যদিও কিছু শাঁস সেট হবে SIGINT মৃত্যু হিসাবে একই নয় $?তবে এটা প্রায়ই SIGINT দ্বারা একটি মৃত্যুর রিপোর্ট করতে (সিস্টেমে যেখানে SIGINT 2 যা সর্বাধিক হয়) জন্য ব্যবহার করা হয়ে, উভয় ক্ষেত্রেই একই মান)।

তবে bash, ksh93বা ফ্রিবিএসডি এর পক্ষে shএটি কার্যকর হয় না। সেই 130 প্রস্থান স্থিতিটিকে সাইন্ট দ্বারা মৃত্যু হিসাবে বিবেচনা করা হবে না এবং সেখানে কোনও পিতামহ স্ক্রিপ্ট বাতিল করা হবে না

সুতরাং, সম্ভবত আরও ভাল বিকল্প হ'ল স্বাক্ষর পাওয়ার পরে স্বাক্ষর দিয়ে নিজেকে হত্যা করা:

trap '
  trap - INT # restore default INT handler
  kill -s INT "$$"
' INT

1
জিলিসের উত্তর "কেন" ব্যাখ্যা করে। একটি হিসাবে অর্থবোধক উদাহরণ, বিবেচনা  for f in *.txt; do vi "$f"; cp "$f" newdir; done। যদি ব্যবহারকারী কোনও ফাইল সম্পাদনার সময় Ctrl + C টাইপ করেন তবে viকেবল একটি বার্তা প্রদর্শিত হবে। এটি যুক্তিসঙ্গত বলে মনে হয় যে ব্যবহারকারী ফাইল সম্পাদনা শেষ করার পরে লুপটি চালিয়ে যাওয়া উচিত। (এবং হ্যাঁ, আমি জানি যে আপনি বলতে পারেন vi *.txt; cp *.txt newdir; আমি forউদাহরণ হিসাবে কেবল লুপটি জমা দিচ্ছি ))
স্কট

@ স্কট, ভাল পয়েন্ট। যদিও vi( vimকমপক্ষে ভাল ) isigসম্পাদনা করার সময় tty অক্ষম করে ( :!cmdযদিও আপনি চালানোর সময় এটি স্পষ্টভাবে হয় না এবং এটি সেই ক্ষেত্রে খুব বেশি প্রয়োগ হয়)।
স্টাফেন চেজেলাস

@ টিম, আপনার সম্পাদনায় সংশোধনের জন্য আমার সম্পাদনা দেখুন।
স্টাফেন চেজেলাস

@ স্টাফেন চ্যাজেলাস ধন্যবাদ সুতরাং এটি কারণ হ'ল pingসাইন্ট পাওয়ার পরে 0 দিয়ে প্রস্থান করে। আমি যখন একই জায়গায় ব্যাশ স্ক্রিপ্টের sudoপরিবর্তে একইরকম আচরণ পেয়েছিলাম pingতবে সাইন ইন sudoকরার পরে 1 দিয়ে প্রস্থান করে। unix.stackexchange.com/questions/479023/…
টিম

13

ব্যাখ্যাটি হ'ল বাশ http://www.cons.org/cracauer/sigint.html প্রতি স্বাক্ষর এবং সিকুইটিটির জন্য ডাব্লুসিই (অপেক্ষা এবং সমবায় প্রস্থান) প্রয়োগ করে । এর অর্থ হ'ল বাশ কোনও প্রক্রিয়াটি প্রস্থান হওয়ার অপেক্ষার সময় সাইন ইন বা সাইনকিট গ্রহণ করে, প্রক্রিয়াটি শেষ না হওয়া পর্যন্ত এটি অপেক্ষা করবে এবং প্রক্রিয়াটি সেই সংকেতটিতে উপস্থিত থাকলে নিজেই প্রস্থান করবে। এটি নিশ্চিত করে যে যে প্রোগ্রামগুলি তাদের ব্যবহারকারী ইন্টারফেসে সিগিন্ট বা সিগুয়েট ব্যবহার করে তারা প্রত্যাশার মতো কাজ করবে (যদি সংকেত প্রোগ্রামটি শেষ করতে না দেয় তবে স্ক্রিপ্টটি স্বাভাবিকভাবে চলতে থাকবে)।

সিগিনেট বা সিগুয়েট ধরা পরে এমন প্রোগ্রামগুলির সাথে একটি খারাপ দিক উপস্থিত হয় তবে তার কারণে শেষ হয় তবে তাদের কাছে সিগন্যালটি পুনরায় পাঠানোর পরিবর্তে একটি সাধারণ প্রস্থান () ব্যবহার করে। এই জাতীয় প্রোগ্রামগুলিকে কল করে এমন স্ক্রিপ্টগুলিকে বাধা দেওয়া সম্ভব নয়। আমি মনে করি পিং এবং পিং 6 এর মতো প্রোগ্রামগুলিতে আসল ফিক্স রয়েছে।

অনুরূপ আচরণটি ksh93 এবং ফ্রিবিএসডি / বিন / এস দ্বারা প্রয়োগ করা হয়েছে, তবে বেশিরভাগ অন্যান্য শেল দ্বারা নয়।


ধন্যবাদ, এটি অনেক অর্থবোধ করে। আমি লক্ষ করেছি যে সেন্টিমিডি হয় প্রস্থান (130) দিয়ে প্রস্থান করলে ফ্রিবিএসডি এইচ গর্ভপাত হয় না, যা সন্তানের স্বাক্ষর দ্বারা মৃত্যুর রিপোর্ট করার একটি সাধারণ উপায় ( exit(130)আপনি বাধা দিলে উদাহরণস্বরূপ মিক্স একটি কাজ করে mksh -c 'sleep 10;:')।
স্টাফেন চেজেলাস

5

আপনি যেমন লক্ষ করেছেন, এটি অধীনস্থ প্রক্রিয়াতে সাইন্ট প্রেরণের কারণে এবং এই প্রক্রিয়াটি প্রস্থান করার পরেও শেলটি অবিরত থাকবে।

এটিকে আরও ভালভাবে পরিচালনা করতে, আপনি যে কমান্ডগুলি চালাচ্ছেন তার প্রস্থান স্থিতি পরীক্ষা করতে পারেন। ইউনিক্স রিটার্ন কোড উভয়ই পদ্ধতিটি এনকোড করে কোন প্রক্রিয়াটি (সিস্টেম কল বা সিগন্যাল) থেকে বেরিয়ে আসে এবং কোন মানটি কী পাস হয় exit()বা কোন সংকেত প্রক্রিয়াটি বন্ধ করে দেয়। এটি সবই জটিল, তবে এটি ব্যবহারের দ্রুততম উপায়টি হ'ল জেনে রাখা যে যে প্রক্রিয়াটি সিগন্যালের মাধ্যমে শেষ হয়ে গিয়েছিল তার একটি শূন্য-শূন্য রিটার্ন কোড থাকবে। এইভাবে, আপনি যদি আপনার স্ক্রিপ্টে রিটার্ন কোডটি পরীক্ষা করেন, অপ্রয়োজনীয় sleepকলগুলির মতো অসচ্ছলতার প্রয়োজনীয়তা অপসারণ করে যদি শিশু প্রক্রিয়াটি সমাপ্ত হয় তবে আপনি নিজেকে প্রস্থান করতে পারবেন । আপনার স্ক্রিপ্ট জুড়ে এটি করার একটি দ্রুত উপায়টি হ'ল ব্যবহার করা set -e, যদিও এটির আদেশের জন্য কয়েকটি টুইটের প্রয়োজন হতে পারে যার প্রস্থান স্থিতি প্রত্যাশিত ননজারো।


1
সেট-ই
ব্যাশে

"সঠিকভাবে কাজ করে না" এর অর্থ কী? আমি এটি সফলভাবে ব্যাশ 3 এ ব্যবহার করেছি, তবে সম্ভবত কিছু প্রান্তের কেস রয়েছে।
টম হান্ট

কয়েকটি সাধারণ ক্ষেত্রে, বাশ 3 ত্রুটি থেকে প্রস্থান করেছে। সাধারণ ক্ষেত্রে এটি ঘটেনি। একটি সাধারণ ফলাফল হিসাবে, লক্ষ্য তৈরি করতে ব্যর্থ হওয়ার সময় মেক থামেনি এবং এটি এমন একটি মেকফাইল থেকে ছিল যা সাব-ডিরেক্টরিতে লক্ষ্যমাত্রার তালিকায় কাজ করেছিল। ডেভিড কর্ন এবং আমাকে ব্যাশ 4 এর জন্য বাগ ঠিক করতে তাকে বোঝাতে ব্যাশ রক্ষণাবেক্ষণকারীকে অনেক সপ্তাহ মেল করতে হয়েছিল।
স্পষ্টত

4
মনে রাখবেন যে এখানে সমস্যাটি হ'ল pingসাইন্ট পাওয়ার পরে 0 প্রস্থান স্থিতির সাথে ফিরে আসে এবং bashতারপরে যদি সেই ঘটনাটি ঘটে তবে তা নিজেই প্রাপ্ত স্বাক্ষরটিকে উপেক্ষা করে। একটি "সেট-ই" যুক্ত করা বা প্রস্থান স্থিতি পরীক্ষা করা এখানে সহায়তা করবে না। সাইন ইন একটি স্পষ্ট ফাঁদ যোগ করা সাহায্য করবে।
স্টাফেন চেজেলাস

4

টার্মিনালটি নিয়ন্ত্রণ-সি লক্ষ্য করে এবং INTঅগ্রভাগ প্রক্রিয়া গোষ্ঠীতে একটি সংকেত প্রেরণ করে , এতে শেলটি এখানে অন্তর্ভুক্ত রয়েছে, কারণ pingকোনও নতুন অগ্রভাগ প্রক্রিয়া গোষ্ঠী তৈরি হয়নি। আটকা পড়ে যাচাই করা সহজ INT

#! /bin/bash
trap 'echo oh, I am slain; exit' INT
while true; do
  ping -c5 127.0.0.1
done

কমান্ডটি যদি চালিত হয় তবে একটি নতুন পূর্বভূমি প্রক্রিয়া গোষ্ঠী তৈরি করেছে, তবে নিয়ন্ত্রণ-সি সেই প্রক্রিয়া গোষ্ঠীতে যাবে, না শেলের দিকে। সেক্ষেত্রে শেলটির প্রস্থান কোডগুলি পরীক্ষা করা প্রয়োজন, কারণ এটি টার্মিনাল দ্বারা সিগন্যাল করা হবে না।

( INTশাঁস মধ্যে হ্যান্ডলিং অবিশ্বাস্য রকমের পথ জটিল যেতে পারে,, যেমন শেল কখনও কখনও সংকেত উপেক্ষা করার প্রয়োজন, এবং কখনও কখনও না উত্স ডুব যদি জানতে আগ্রহী, অথবা Ponder। tail -f /etc/passwd; echo foo)


এই ক্ষেত্রে, সমস্যাটি হ্যান্ডলিংয়ের সংকেত নয় তবে বাশ স্ক্রিপ্টে জবকন্ট্রোল করে যদিও এটি করা উচিত নয়, আরও তথ্যের জন্য আমার উত্তরটি দেখুন
তাড়াতাড়ি

নতুন প্রসেস গ্রুপে সিগিন্ট যাওয়ার জন্য, কমান্ডটি টার্মিনালের অগ্রভাগ প্রক্রিয়া গোষ্ঠী তৈরি করতে টার্মিনালে একটি আইওএসটিএল () করতে হবে। pingএখানে একটি নতুন প্রক্রিয়া গ্রুপ শুরু করার কোনও কারণ নেই এবং আমি ওপির সমস্যাটি পুনরুত্পাদন করতে পারে এমন পিংয়ের সংস্করণ (দেবিয়ান-এ iputils) কোনও প্রক্রিয়া গ্রুপ তৈরি করে না।
স্টাফেন চেজেলাস

1
মনে রাখবেন যে এটি টার্মিনাল নয় যা সিগিন্ট প্রেরণ করে, এটি একটি অনস্কেপড (সাধারণত লেখনি দ্বারা সাধারণত ^ ভি) character সি অক্ষর প্রাপ্তির পরে টিটি ডিভাইসটির (লাইন / ডি / টাইটোমোথিং ডিভাইসের ড্রাইভার) টার্মিনাল থেকে।
স্টাফেন চেজেলাস

2

ঠিক আছে, আমি sleep 1ব্যাশ স্ক্রিপ্টে একটি যুক্ত করার চেষ্টা করেছি , এবং ঠুং ঠুং শব্দ!
এখন আমি এটি দুটি দিয়ে থামাতে সক্ষম Ctrl+C

চাপলে Ctrl+C, SIGINTবর্তমানে সম্পাদিত প্রক্রিয়াটিতে একটি সংকেত প্রেরণ করা হয়, লুপের ভিতরে কোন কমান্ডটি চালানো হয়েছিল। তারপরে সাব - শেল প্রক্রিয়াটি লুপের পরবর্তী কমান্ডটি চালিয়ে যায়, এটি অন্য প্রক্রিয়া শুরু করে। স্ক্রিপ্টটি থামাতে সক্ষম হওয়ার জন্য দুটি SIGINTসিগন্যাল প্রেরণ করা প্রয়োজন , একটি কার্যকর অবস্থায় বর্তমান কমান্ডকে বাধা দিতে এবং একটি সাব - শেল প্রক্রিয়াটিকে বাধাগ্রস্থ করতে ।

sleepকল ছাড়াই স্ক্রিপ্টে , Ctrl+Cসত্যিই দ্রুত এবং অনেক বার টিপলে কাজ করা মনে হয় না এবং লুপটি থেকে বেরিয়ে আসা সম্ভব হয় না। আমার ধারণা হ'ল বর্তমান সম্পাদিত প্রক্রিয়াটির বাধাগুলি এবং পরবর্তীটির সূচনার মধ্যবর্তী সময়ে সঠিক মুহূর্তে দু'বার চাপ দেওয়া যথেষ্ট দ্রুত নয়। প্রতিটি Ctrl+Cচাপানো SIGINTলুপের ভিতরে সম্পাদিত একটি প্রক্রিয়াতে একটি প্রেরণ করবে , তবে দুটিও সাবশেলের কাছে পাঠানো হবে না ।

স্ক্রিপ্টে sleep 1, এই কলটি এক সেকেন্ডের জন্য মৃত্যুদন্ড স্থগিত করবে এবং প্রথম Ctrl+C(প্রথম SIGINT) দ্বারা বাধা দেওয়া হলে , সাবশেল পরবর্তী কমান্ডটি কার্যকর করতে আরও সময় নিবে। সুতরাং এখন, দ্বিতীয় Ctrl+C(দ্বিতীয় SIGINT) সাব - শেলটিতে যাবে , এবং স্ক্রিপ্টের সম্পাদন শেষ হবে।


আপনি ভুল হয়ে আছেন, সঠিকভাবে কাজ করার শেলটিতে, একটি একক ^ C যথেষ্ট পরিমাণে পটভূমির জন্য আমার উত্তর দেখুন।
স্কিলে

ঠিক আছে, আপনি ভোটাভুটি হয়ে গেছেন এবং বর্তমানে আপনার উত্তরের স্কোর -১ রয়েছে বিবেচনা করে, আমি আপনার উত্তরটি গুরুত্ব সহকারে নেব বলে আমি খুব বেশি বিশ্বাস করি না।
ভাগ্নে

কিছু লোক যে সর্বস্বান্ত হয় তা হ'ল জবাবের মানের সাথে সম্পর্কিত নয়। আপনার যদি দুটি বার ^ সি টাইপ করতে হয় তবে আপনি অবশ্যই ব্যাশ বাগের শিকার। আপনি কি অন্য একটি শেল চেষ্টা করেছেন? আপনি কি বাস্তব বোর্ন শেলটি ব্যবহার করে দেখেছেন?
সুন্দরভাবে

শেলটি যদি সঠিকভাবে কাজ করে তবে, এটি একই প্রক্রিয়া গোষ্ঠীর স্ক্রিপ্ট থেকে সমস্ত কিছু চালায় এবং তারপরে একটি ^ সি যথেষ্ট sufficient
স্কিচলি

1
এই উত্তরটিতে @ নেফিটোম যে আচরণটি বর্ণনা করে তা স্ক্রিপ্টের বিভিন্ন কমান্ড দ্বারা ব্যাখ্যা করা যেতে পারে যে তারা Ctrl-C প্রাপ্ত হলে আলাদাভাবে আচরণ করবে। যদি একটি ঘুম উপস্থিত থাকে, অত্যধিক সম্ভাবনা রয়েছে যে ঘুম সঞ্চালনের সময় Ctrl-C প্রাপ্ত হবে (লুপের সমস্ত কিছু দ্রুত আছে ধরে নিয়ে)। নিদ্রাটি 130 এর প্রস্থান মূল্য সহ নিহত হয় sleep ঘুমের পিতামাতা, একটি শেল, লক্ষ্য করে যে ঘুমটি সিগিন্ট দ্বারা হত্যা করেছিল এবং প্রস্থান করে। তবে যদি স্ক্রিপ্টটিতে ঘুম না থাকে তবে Ctrl-C পরিবর্তে পিংয়ে যায় যা 0 দিয়ে বেরিয়ে এসে প্রতিক্রিয়া জানায়, তাই প্যারেন্ট শেল পরবর্তী কমান্ডটি সম্পাদন করে।
জোনাথন হার্টলি

0

এটা চেষ্টা কর:

#!/bin/bash
while true; do
   echo "Ctrl-c works during sleep 5"
   sleep 5
   echo "But not during ping -c 5"
   ping -c 5 127.0.0.1
done

এখন প্রথম লাইনটি এতে পরিবর্তন করুন:

#!/bin/sh

এবং আবার চেষ্টা করুন - দেখুন পিংটি এখন বাধাপ্রাপ্ত কিনা।


0
pgrep -f process_name > any_file_name
sed -i 's/^/kill /' any_file_name
chmod 777 any_file_name
./any_file_name

উদাহরণস্বরূপ pgrep -f firefox, চলমান পিআইডি গ্রেপ করবে firefoxএবং এই পিআইডি নামক কোনও ফাইলে সংরক্ষণ করবে any_file_name। 'sed' কমান্ডটি kill'any_file_name' ফাইলটিতে পিআইডি নম্বরটির শুরুতে যুক্ত করবে । তৃতীয় লাইন any_file_nameএক্সিকিউটেবল ফাইল করবে । এখন লাইন ফাইলের মধ্যে উপলব্ধ পিআইডি হত্যা করবে any_file_name। একটি ফাইলে উপরোক্ত চারটি লাইন লিখতে এবং সেই ফাইলটি কার্যকর করে Control- করতে পারে C। আমার জন্য একেবারে ভাল কাজ।


0

কারও যদি এই bashবৈশিষ্ট্যটির কোনও স্থির করতে আগ্রহী এবং এর পিছনে দর্শনে এতটা না , তবে এখানে একটি প্রস্তাব দেওয়া হল:

সমস্যাযুক্ত কমান্ড সরাসরি চালাবেন না, তবে একটি মোড়ক থেকে ক) এটি সমাপ্তির জন্য অপেক্ষা করে খ) সংকেতগুলিতে গন্ডগোল করে না এবং গ) ডাব্লুসিই প্রক্রিয়া নিজেই প্রয়োগ করে না , তবে কেবলমাত্র একটি পাওয়ার পরে মারা যায় SIGINT

awkএর system()কার্যকারিতা সহ এ জাতীয় একটি মোড়ক তৈরি করা যেতে পারে ।

$ while true; do awk 'BEGIN{system("ping -c5 localhost")}'; done
PING localhost(localhost (::1)) 56 data bytes
64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.082 ms
64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.087 ms
^C
--- localhost ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1022ms
rtt min/avg/max/mdev = 0.082/0.084/0.087/0.009 ms
[3]-  Terminated              ping -c5 localhost

ওপির মতো স্ক্রিপ্টে রাখুন:

#!/bin/bash
while true; do
        echo -e "\n*** DATE:" `date` " ***";
        echo "********************************************"
        awk 'BEGIN{system(ARGV[1])}' "ping -c5 ${1-localhost}"
done

-3

আপনি একটি সুপরিচিত বাশ বাগের শিকার। স্ক্রিপ্টগুলির জন্য বাশ জবকন্ট্রোল করে যা একটি ভুল।

যা ঘটে তা হ'ল বাশ বাহ্যিক প্রোগ্রামগুলিকে স্ক্রিপ্টের জন্য ব্যবহারের চেয়ে আলাদা প্রক্রিয়া গোষ্ঠীতে চালায়। যেহেতু টিটিওয়াই প্রসেসগ্রুপটি বর্তমানের অগ্রভাগের প্রক্রিয়াটির গোষ্ঠীতে সেট করা আছে, কেবলমাত্র এই অগ্রভাগ প্রক্রিয়াটি মারা যায় এবং শেল স্ক্রিপ্টের লুপটি অবিরত থাকে।

যাচাই করতে: একটি বিল্টিন প্রোগ্রাম হিসাবে pgrp (1) প্রয়োগ করে এমন একটি সাম্প্রতিক বোর্ন শেল সংগ্রহ করুন এবং সংকলন করুন, তারপরে স্ক্রিপ্ট লুপটিতে একটি / বিন / স্লিপ 100 (বা / usr / বিন / ঘুম) যুক্ত করুন এবং তারপরে শুরু করুন বোর্ন শেল স্লিপ কমান্ডের জন্য প্রসেস আইডি এবং স্ক্রিপ্টটি চালিত ব্যাশের জন্য আপনি পিএস (1) ব্যবহার করার পরে, pgrp <pid>"<পিড>" স্লিপ এবং স্ক্রিপ্টটি চালিত ব্যাশের প্রক্রিয়া আইডি দ্বারা "<পিড>" কল করে প্রতিস্থাপন করুন। আপনি বিভিন্ন প্রক্রিয়া গ্রুপ আইডি দেখতে পাবেন। pgrp < /dev/pts/7বর্তমান টিটিটি প্রক্রিয়া গ্রুপটি পাওয়ার জন্য এখন (স্ক্রিপ্ট দ্বারা ব্যবহৃত টিটিটি দ্বারা টিটিটির নাম প্রতিস্থাপন করুন) এর মতো কিছু কল করুন । টিটিওয়াই প্রসেস গ্রুপটি স্লিপ কমান্ডের প্রক্রিয়া গোষ্ঠীর সমান করে।

ঠিক করার জন্য: একটি আলাদা শেল ব্যবহার করুন।

সাম্প্রতিক বোর্ন শেল সূত্রগুলি আমার চতুর সরঞ্জাম প্যাকেজে রয়েছে যা আপনি এখানে পেতে পারেন:

http://sourceforge.net/projects/schilytools/files/


এর কোন সংস্করণ bash? bashআপনি যদি -M বা -i বিকল্পটি পাস করেন তবে আফাইক কেবল এটিই করে।
স্টাফেন চেজেলাস

দেখে মনে হচ্ছে এটি বাশ ৪-এর ক্ষেত্রে আর প্রযোজ্য নয় তবে যখন ওপিতে এ জাতীয় সমস্যা রয়েছে, তখন সে বশ 3 ব্যবহার করবে বলে মনে হচ্ছে
স্পষ্টভাবে

Bash3.2.48 বা ব্যাশ 3.0.16 বা ব্যাশ -০.০৫ বি (দিয়ে চেষ্টা করা bash -c 'ps -j; ps -j; ps -j') দিয়ে পুনরুত্পাদন করা যাবে না ।
স্টাফেন চেজেলাস

আপনি বাশকে যেমন কল করবেন তখন এটি অবশ্যই ঘটে /bin/sh -ce। লেয়ার্ড মেক কলটি বাতিল smakeকরার অনুমতি ^Cদেওয়ার জন্য একটি চলমান কমান্ডের জন্য প্রসেস গ্রুপটিকে স্পষ্টভাবে মেরে ফেলতে আমি একটি কুরুচিপূর্ণ কাজের সংযোগ যোগ করতে হয়েছিল। আপনি কি পরীক্ষা করেছেন যে বাশ প্রক্রিয়া গ্রুপটি প্রবর্তন প্রক্রিয়া গ্রুপ আইডি থেকে শুরু করেছিল কিনা তা দিয়ে?
স্পষ্টত

ARGV0=sh bash -ce 'ps -j; ps -j; ps -j'সমস্ত 3 পিএস অনুরোধগুলিতে পিএস এবং ব্যাশের জন্য একই পিজিডি প্রতিবেদন করে। (ARGV0 = sh হ'ল zshargv পাস করার উপায় [0])।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.