শেল স্ক্রিপ্টটি বিরতি দিতে কোনও কী টিপুন, আবার শুরু করতে টিপুন


11

আমি একটি এপিআই পরীক্ষার জন্য একটি শেল স্ক্রিপ্ট লিখেছি যা ফাইলগুলি অনুলিপি করে এবং প্রতিটিটির পরে এর অগ্রগতি প্রতিধ্বনি করে।

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

আমি কীভাবে এটি সম্ভব কম কয়েকটি লাইনে যুক্ত করতে পারি?

উত্তর:


12

আপনার স্ক্রিপ্টে আপনাকে কিছু যুক্ত করার দরকার নেই। শেল যেমন একটি কার্যকারিতা অনুমতি দেয়।

  • একটি টার্মিনালে আপনার স্ক্রিপ্ট শুরু করুন।
  • চলাকালীন এবং টার্মিনাল ব্যবহার অবরুদ্ধ করছে ctrl- z। টার্মিনালটি আবার মুক্তি পেয়েছে এবং আপনার বার্তা দেখুন যে প্রক্রিয়াটি বন্ধ হয়ে গেছে। (এটি এখন কর্কস অবস্থায় রয়েছে T, বন্ধ হয়েছে)
  • এখন আপনি যা চান তা করুন। আপনি অন্যান্য প্রক্রিয়া / স্ক্রিপ্টগুলি শুরু করতে এবং ctrl- দিয়ে এগুলি বন্ধ করতে পারেন z
  • jobsটার্মিনালে টাইপ করুন বা সমস্ত বন্ধ হওয়া কাজের তালিকা দিন।
  • আপনার স্ক্রিপ্টটি চালিয়ে যেতে দিন fg(অগ্রভাগ) টাইপ করুন । এটি অগ্রভাগের প্রক্রিয়া গোষ্ঠীতে আবার কাজ শুরু করে এবং কাজগুলি চলতে থাকে।

একটি উদাহরণ দেখুন:

root@host:~$ sleep 10 # sleep for 10 seconds
^Z
[1]+  Stopped                 sleep 10
root@host:~$ jobs # list all stopped jobs
[1]+  Stopped                 sleep 10
root@host:~$ fg # continue the job
sleep 10
root@host:~$ # job has finished

যেমন আপনি বলেছিলেন, আমি চালাচ্ছি sleep 10; notify-send helloএবং থামাতে CTRL + Z টিপুন, notify-send helloমৃত্যুদণ্ড কার্যকর করুন। যদি দ্বিতীয় কমান্ড কার্যকর হয় তবে প্রথম প্রক্রিয়াটি কীভাবে বন্ধ হবে? তারপরে যদি টাইপ fgকরতাম না তবে কিছুই ঘটতে পারে, যা স্পষ্টতই, যেহেতু দ্বিতীয় কমান্ড ইতিমধ্যে কার্যকর করা হয়েছে
এডওয়ার্ড টরভাল্ডস

দুটি কমান্ড পৃথক হওয়ার কারণ একটি স্ক্রিপ্টে তারা একটি সাব-শেলের মধ্যে থাকতে পারে। এগুলি একটি সাধারণ স্ক্রিপ্টে লিখুন এবং স্ক্রিপ্টটি কার্যকর করুন। তারপরে ctrl-z থামাতে হবে এবং আপনি দ্বিতীয় কমান্ডটি শেষ না হওয়া পর্যন্ত কার্যকর হবে না তা দেখতে পাবেন। লিখন cmd; cmd; cmd;লেখা ভালো হয় cmd <newline> cmd <newline> ...। একটি স্ক্রিপ্ট আপনি লিখতে পারেন বিকল্পভাবে ( cmd; cmd; cmd; ), এটা স্ক্রিপ্ট মত আচরণ করবে, subshell এর bacuse দ্বারা উত্পন্ন(
বিশৃঙ্খলার

আমিও চেষ্টা করেছি sleep 10। আমি যখন 3 সেকেন্ড পরে CTRL + Z টিপুন এবং কয়েক সেকেন্ড পরে পুনরায় শুরু করি এবং লক্ষ্য করেছি যে স্লিপ কমান্ডটি 7 সেকেন্ডেরও কম সময়ে মারা গেছে। যা আপনি যা বলেছেন তার বিপরীত, যেহেতু কমান্ড নেভার্স বন্ধ হয়ে যায় কেবল পটভূমিতে চলে runs
এডওয়ার্ড টরভাল্ডস

অ্যাডওয়ার্ডারওয়াল্ডস আমি এটাও লক্ষ্য করেছি ... এর কোনও মানে নেই। কমান্ডটি straceডি করলাম sleepএবং জানতে পারলাম যে সিস্টেম কলটি ব্যবহৃত হয়েছিল nanosleep()। এটি সিস্টেমকলের একটি সংজ্ঞায়িত আচরণ বলে মনে হচ্ছে nanosleeprestart_syscall()বিযুক্ত সিস্টেম কলকে এমন একটি সময় আর্গুমেন্টের সাথে পুনঃসূচনা করে যা ইতিমধ্যে অতিবাহিত সময়ের জন্য অ্যাকাউন্টে উপযুক্তভাবে সামঞ্জস্য হয় (সংকেত দ্বারা প্রক্রিয়াটি যেভাবে থামানো হয়েছিল সেই সময় সহ)। সেই পৃষ্ঠাটি
বিশৃঙ্খলা

@ চাওস উত্তরের জন্য বেশ কয়েকটি নোট (এগুলিতে অন্তর্ভুক্ত নির্দ্বিধায়): যখন কেউ সিটিআরএল-জেড করেন, কাজটি স্থগিত করা হয় ("থামিয়ে দেওয়া"), তাই এটি এই মুহূর্তে চলছে না, আপনি এটি চালিয়ে যাওয়ার সিদ্ধান্ত নেওয়ার জন্য অপেক্ষা করছেন অগ্রভাগে (প্রাক্তন fg %1:) বা পটভূমিতে (প্রাক্তন bg %1:) (যদি চাকরীগুলি কেবল 1 নম্বর দেয়, উদাহরণস্বরূপ কেবল 1 স্থগিত প্রক্রিয়া, যেমন উদাহরণস্বরূপ বিশৃঙ্খলা দেখানো হয়েছে: কেবলমাত্র [1]+ stopped sleep 10, আপনি %nঅংশটি বাদ দিতে পারেন several যদি বেশ কয়েকটি ব্যাকগ্রাউন্ড প্রক্রিয়া থাকে (চলমান বা থামানো), আপনার নিজের পছন্দমতো একটি মনোনীত করতে হবে সহ: %n(উদা: fg %2
পূর্বেরভাগে

6

আপনি যদি স্ক্রিপ্টের ভিতরে থাকা অবস্থায় স্ক্রিপ্টটি কেবল বিরতি দিতে চান তবে আপনি ঘুমের পরিবর্তে পঠন ব্যবহার করতে পারেন।

তুমি ব্যবহার করতে পার

read -t
read -nস্ক্রিপ্ট চালিয়ে যাওয়ার জন্য একটি অক্ষর পড়ার জন্য টাইমআউট সেট করতে (কার্যকরভাবে কোনও কী চাপুন)

যেহেতু আপনি কোনও কোড সরবরাহ করেন নি, নীচে এটি কীভাবে ব্যবহার করা যেতে পারে তার একটি উদাহরণ।
যদি q টিপ করা হয় তবে read -n1স্ক্রিপ্টটি চাপ না দেওয়া পর্যন্ত স্ক্রিপ্টটি চলতে বাধা দেয়।
যখন একটি কী চাপানো হয় তখন চেকটি পুনরায় সেট করা হয় এবং স্ক্রিপ্টটি স্বাভাবিক হিসাবে লুপটিতে অবিরত থাকে।

while [[ true ]]; do
    read -t2 -n1 check
    if [[ $check == "q" ]];then
        echo "pressed"
        read -n1
        check=""
    else
        echo "not pressed"
    fi
echo "Doing Something"
done

স্ক্রিন আউটপুট গোলমাল করা থেকে টাইপিং প্রতিরোধ করতে আপনি stty -echoবিভাগটির শুরুতে এবং stty echoশেষের দিকেও যুক্ত করতে পারেন


@ মিকসার্ভ আমি ভাবছি না যে ওপটি কী পড়েছে সেদিকে খেয়াল রাখে, তারা কেবল স্ক্রিপ্টটি থামিয়ে আবার শুরু করতে চায়, টার্মিনাল সেটিংসটি সংরক্ষণ করে আপনি কী বোঝাতে চেয়েছেন, আমি কেবল একটি পরিবর্তন করছি যাতে কিছুটা ওভারকিল মনে হয়।

1
@ মিকসার্ভ আহ্ ঠিক আছে, আমি কেবল অনুমান করছিলাম যে সমস্ত স্টিডিন ব্যবহারকারীর কাছ থেকে আসবে।

1

সঙ্গে ddআপনি নির্ভরযোগ্যভাবে একটি ফাইল থেকে একটি একক বাইট পড়তে পারেন। সঙ্গে sttyআপনি একটি সেট করতে পারেন minএকটি টার্মিনাল পড়ে এবং যোগ্যতা বাইটের সংখ্যা timeএক সেকেন্ডের দশমাংশ আউট। এই দুটি একত্রিত করুন এবং আপনি sleepসম্পূর্ণরূপে ছাড়াই করতে পারেন , আমি মনে করি এবং টার্মিনালের পড়ার সময়সীমা আপনার জন্য কাজটি করতে দিন:

s=$(stty -g </dev/tty)
(while stty raw -echo isig time 20 min 0;test -z "$(
dd bs=1 count=1 2>/dev/null; stty "$s")" || (exec sh)
do echo "$SECONDS:" do your stuff here maybe                             
   echo  no sleep necessary, I think                                                          
   [ "$((i+=1))" -gt 10 ] && exit                                                             
done       
) </dev/tty

এটি একটি সামান্য উদাহরণ whileলুপ যা আমি আপনাকে চেষ্টা করে দেখার জন্য উপহাস করেছি। প্রতি দুই সেকেন্ড ddপরে এর চেষ্টা করার চেষ্টা করে stdin- এর থেকে পুনঃনির্দেশিত /dev/tty- এবং whileলুপ লুপগুলি। এটি বা সময়সীমা dd ছাড়ায় না কারণ আপনি একটি কী টিপেন - এমন ক্ষেত্রে একটি ইন্টারেক্টিভ শেলটি চাওয়া হয়।

এখানে একটি পরীক্ষা চালানো হয়েছে - প্রতিটি লাইনের শিরোনামে মুদ্রিত সংখ্যাগুলি শেল ভেরিয়েবলের মান $SECONDS:

273315: do your stuff here maybe
no sleep necessary, I think
273317: do your stuff here maybe
no sleep necessary, I think
273319: do your stuff here maybe
no sleep necessary, I think
273321: do your stuff here maybe
no sleep necessary, I think
sh-4.3$ : if you press a key you get an interactive shell
sh-4.3$ : this example loop quits after ten iterations
sh-4.3$ : or if this shell exits with a non-zero exit status
sh-4.3$ : and speaking of which, to do so you just...
sh-4.3$ exit
exit
273385: do your stuff here maybe
no sleep necessary, I think
273387: do your stuff here maybe
no sleep necessary, I think
273389: do your stuff here maybe
no sleep necessary, I think
273391: do your stuff here maybe
no sleep necessary, I think
273393: do your stuff here maybe
no sleep necessary, I think
273395: do your stuff here maybe
no sleep necessary, I think
273397: do your stuff here maybe
no sleep necessary, I think

stty saneস্টেটি সেটিং পরিবর্তন করার পরে কি আপনার ব্যবহার করা উচিত নয় , আমি ভুল হতে পারি তবে আপনি এগুলিকে অন্য কোথাও রিসেট করছেন বলে মনে হচ্ছে না?

@ জিডার - না, আমি স্ক্রিপ্টের শীর্ষে টার্মিনালের অবস্থাটি সংরক্ষণ করি না s=$(stty -g </dev/tty)। কল ddকরার সাথে সাথে আমি আবার এটি দিয়ে পুনরুদ্ধার করব stty "$s"। টার্মিনাল স্টেটটি সাব-শেলগুলির বিষয়ে চিন্তা করে না এবং তাই সেগুলির সেটিংস পিতা-মাতার শেল নির্বিশেষে আটকে থাকে। stty saneআপনি যা করতে চান তা অগত্যা নয় - রাষ্ট্রটি saneএই মুহুর্তে অনুমান করার চেয়ে আপনি যেভাবে রাজ্যটি পেয়েছিলেন সেটিকে পুনরুদ্ধার করা ভাল । আমি যদি এটি পুনরুদ্ধার না করতাম echoতবে সেগুলি সমস্ত জায়গাতেই থাকবে। আংশিকভাবে কেন আমি এত দেরি করেছিলাম তা খুঁজে বের করা - আমি যখন পরীক্ষার কাজ শুরু করি তখন আপনার উত্তর এখানে ছিল না।
মাইকসার্ভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.