পটভূমিতে চলমান একটি শেল স্ক্রিপ্ট হত্যা


12

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

এটি অবিচ্ছিন্নভাবে চালিত করতে, আমি ব্যবহার করেছি while true; এটার মত:

while true;
do #a set of commands that use the inotifywait utility
end

আমি এটিকে একটি ফাইলে সংরক্ষণ করে এটি কার্যকর করতে /binপেরেছি। এটি পটভূমিতে চালিত করতে, আমি nohup <script-name> &টার্মিনালটি ব্যবহার করে এবং বন্ধ করে দিয়েছি।

আমি জানি না কীভাবে আমি এই স্ক্রিপ্টটি বন্ধ করব। আমি এখানে উত্তরগুলি এবং খুব ঘনিষ্ঠভাবে সম্পর্কিত প্রশ্নটি এখানে দেখেছি ।

আপডেট 1: নীচের @ ইনফেক্টেড রুটের উত্তরের ভিত্তিতে, আমি নিম্নলিখিত কৌশলটি ব্যবহার করে আমার সমস্যা সমাধান করতে সক্ষম হয়েছি। প্রথম ব্যবহার

ps -aux | grep script_name

এবং sudo kill -9 <pid>প্রক্রিয়াগুলি মেরে ফেলতে ব্যবহার করুন । আমি তখন ফিরে এসে আইডি ফেরত pgrep inotifywaitব্যবহার sudo kill -9 <pid>করতে হয়েছিল।

এটি কাজ করে তবে আমি মনে করি এটি একটি নোংরা উপায়, আমি আরও ভাল উত্তর খুঁজছি।

আপডেট 2: উত্তরে 2 টি প্রক্রিয়া হ'ল । এটি গুরুত্বপূর্ণ কারণ কমান্ড লাইনে স্ক্রিপ্টটি চালানো 2 প্রক্রিয়া শুরু করে, 1 নিজেই স্ক্রিপ্ট এবং 2, ইনোটাইফাই প্রক্রিয়া



2
-9অপশনটি অপসারণ করা killএবং কেবল ব্যবহার করা killঝামেলা জাগিয়ে তুলবে।
শ্রী

1
সাবাস। পুনরায় শুল্ক নগদ বাক্সে কিছু '$$' পেতে, আমি জোর দিয়ে বলতে চাই যে -9বিকল্পটি killএখানে মোটামুটি হবে । : পি
সিন্ট্যাক্সেরর

সম্পূর্ণতার জন্য: উভয় প্রক্রিয়া একবারে মেরে ফেলার জন্য একটি পরিষ্কার পদ্ধতি রয়েছে: প্রক্রিয়াগুলি পৃথকভাবে হত্যার পরিবর্তে আপনি স্ক্রিপ্টের প্রক্রিয়া গোষ্ঠীকে একবারে মেরে ফেলতে পারেন। Pgid শেল স্ক্রিপ্ট মূল প্রক্রিয়া এর PID যেমন এবং একই killআপনার একটি বিয়োগ সঙ্গে pgid উপসর্গ: kill -- -<pgid>, kill -9 -<pgid>, ইত্যাদি
cg909

উত্তর:


6

killallকমান্ডগুলি উন্নত করতে, ব্যবহার করতে এবং সংযুক্ত করতে:

ps -aux | grep script_name
killall script_name inotifywait

বা এক লাইনে সবকিছু করুন:

killall `ps -aux | grep script_name | grep -v grep | awk '{ print $1 }'` && killall inotifywait

আপনার উপরের সমাধানটি কাজ করে তবে একটি লাইন কমান্ড নয়। আপনি এটি পরীক্ষা করতে পারে। আমি একটি ত্রুটি পেয়েছি: কোনও প্রক্রিয়া নেই
light94

@ লাইট94 এর Error: no processঠিক অর্থ হওয়া উচিত যে আপনি ইতিমধ্যে এটি হত্যা করেছেন। আপনি ভিএলসি এবং জিনির মতো আরও দুটি প্রোগ্রাম খোলার পরিবর্তে এগুলি পরীক্ষা করে দেখতে পারেন।
13:51

আরে @ ক্রিমফ্রেইচে, যেমন আর্লার বলেছেন যে আপনার কোডটি কাজ করে .. তবে আমি বিকল্প সমাধানগুলি এবং সর্বাধিক সাধারণ সমাধান খুঁজছি যা হ'ল কিল <পিড> ব্যবহার করা। যেহেতু, আমার স্ক্রিপ্টটি সেই পদ্ধতিতে শেষ হয় না, তাই আমার কোডটি অনুপযুক্ত হলে আমি কিছুটা উদ্বিগ্ন? আপনি আমাকে গাইড করতে পারেন?
light94

আপনি grep -v grepপরিণত করে চালু grep script_nameকরতে পারেন grep -e "[s]cript_name"
এনমিহেলস

3

ব্যবহার করে পটভূমির কাজগুলি তালিকাবদ্ধ করুন

# jobs

তারপরে চাকরির পূর্বের সংখ্যাটি বেছে নিন এবং রান করুন

উদাহরণ

# fg 1 

এখানে চিত্র বর্ণনা লিখুন

অগ্রণীতে নিয়ে আসবে।

তারপরে এটি সিটিআরএল + সি বা স্ক্রিপ্টের পিআইডি ব্যবহারের সহজ উপায় ব্যবহার করে হত্যা করুন

ps -aux | grep script_name

এখানে চিত্র বর্ণনা লিখুন

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

sudo kill -9 pid_number_here

2
প্রথম বিকল্পটি আমার ক্ষেত্রে বৈধ নয় কারণ আমি স্ক্রিপ্টটি উল্লেখ করার পরে শেলটি বন্ধ করি এবং আমার মনে হয় জবস কমান্ডটি একই শেলের জন্য কেবল কাজ করে। এছাড়াও, আমি দ্বিতীয় বিকল্পটি চেষ্টা করেছিলাম এবং এটি প্রক্রিয়াটি হারাতে পারে তবে আমি যখন পিগ্রেপ ইনোটিফয়েট করি, তখনও আমি এটিকে সেখানে প্রক্রিয়া হিসাবে দেখতে পারি।
হালকা 9

আপনি শেলটি বন্ধ করে দিলেও জবস কাজের তালিকা দেবে। তবুও প্রক্রিয়াটি শেষ হবে এটি সেখানে থাকবে।
বাবিন লনস্টন

2
আমি চেষ্টা করেছিলাম কিন্তু তা হয়নি।
হালকা 9

@ light94 আপনি ঠিক বলেছেন এখানে প্রায়শই ঘটেছিল যে jobsকমান্ডটি কেবল শেলের মধ্যে থাকা অবস্থায় চলমান কাজগুলি প্রদর্শন করে । একবার আমি একটি নির্দিষ্ট টার্মিনাল উইন্ডোটি বন্ধ করে দিলে, তাদের অ্যাক্সেসের একমাত্র উপায়টি ছিল ps(তার জন্য উপরে দেখুন)। সুতরাং এটি নিশ্চিত যে আপনি এটি তৈরি করছেন না।
সিনট্যাক্সেরর

2

আপনি ps+ ব্যবহার করতে পারেন grepবা pgrepপ্রক্রিয়া নাম / পিড পেতে ; পরে killall/ pkillপ্রক্রিয়া নাম killকিল ব্যবহার বা পিড মারার জন্য ব্যবহার । নিম্নলিখিত সমস্ত কাজ করা উচিত।

killall $(ps aux | grep script_name | grep -v grep | awk '{ print $1 }') && killall inotifywait
(ps -ef | grep script_name | grep -v grep | awk '{ print $1 }' | xargs killall) && killall inotifywait
(ps -ef | grep script_name | grep -v grep | awk '{ print $2 }' | xargs kill) && killall inotifywait
(pgrep -x script_name | xargs kill) && pkill -x inotifywait
pkill -x script_name && pkill -x inotifywait

সর্বাধিক গুরুত্বপূর্ণ বিষয়টি হ'ল আপনার নিশ্চিত হওয়া উচিত যে আপনি যে সঠিক প্রক্রিয়াটি (গুলি) হত্যা করার আশা করছেন কেবল তাকেই হত্যা করেছেন।

pkill/ সঠিক নামের চেয়ে pgrepএকটি প্যাটার্নের সাথে মেলে , তাই আরও বিপজ্জনক; সঠিক নামের সাথে মিলিয়ে এখানে যুক্ত করা হয়েছে ।-x

এছাড়াও, pgrep/ যখন pkillআপনার প্রয়োজন হতে পারে ব্যবহার করার সময়

  • -fপূর্ণ কমান্ড লাইন মেলে (যেমন ps auxকরে)
  • -a প্রক্রিয়া নাম মুদ্রণ করতে।

উপরেরটি কার্যকর করার পরে, আমি প্রতিটিটিতে ব্যবহারের ত্রুটি পেয়েছি। আমি স্ক্রিপ্টের নামটি আটকানো এবং প্রতিস্থাপন করছি। আমি আউটপুট হিসাবে
কিলের

স্ক্রিপ্ট_নাম চলছে? এটি আমার (ডেবিয়ান জেসি) পক্ষে কাজ করে
হংএক্সু চেন

হ্যাঁ এটি চলছে এবং আপনার সমাধানটি উপরে @ ক্রিমফ্রেইচের সমাধানগুলির মতো প্রায় একই তাই আমি এটি একইভাবে কাজ করার প্রত্যাশা করেছি: /
লাইট94

হ্যাঁ, আমি কিছুটা তা করার, বিশেষ করে যোগ সম্ভাব্য উপায় সংক্ষেপিত ছিল pgrep/ pkill। যদি এটি এখনও ভুল হয়ে যায় আপনি pgrep-x ছাড়াই চেষ্টা করতে পারেন । মূলত আমি মনে করি না যে অন্যান্য প্রক্রিয়াগুলি মিলেছে কিনা তা পরীক্ষা না করেই এক লাইনের কমান্ডের মধ্যে প্রক্রিয়াটি মেরে ফেলা ভাল good
হংকক্সু চেন

1

আপনি সম্ভবত বলতে পারেন এটি করার জন্য প্রচুর উপায় রয়েছে।

আপনার "আপডেট # 2" সম্পর্কিত - সাধারণভাবে বলতে গেলে, পিতামাতা-শিশুক্রমক্রমের যে কোনও প্রক্রিয়া বন্ধ করা সাধারণত সম্পর্কিতভাবে সমস্ত সম্পর্কিত প্রক্রিয়া বন্ধ করে দেবে। তবে এর ব্যতিক্রম অনেক আছে। আদর্শভাবে, আপনি একটি প্রক্রিয়া ট্রিতে চূড়ান্ত 'শিশু' অবসান করতে চান, তারপরে এই সন্তানের পিতামাতারা তাদের চালানোর মতো অন্য কোনও কাজ না করে যদি প্রস্থান করা উচিত। তবে আপনি যদি কোনও পিতামাতাকে হত্যা করেন তবে পিতা-মাতার মৃত্যুর পরে বাচ্চাদের কাছে সিগন্যালটি রিলে করা উচিত এবং বাচ্চারা পাশাপাশি প্রস্থান করতে হবে - তবে এমন কিছু ঘটনাও রয়েছে যেখানে বাচ্চাদের প্রক্রিয়াগুলি সিগন্যালটিকে উপেক্ষা করতে পারে (ফাঁদ বা অনুরূপ প্রক্রিয়াগুলির মাধ্যমে) এবং চালিয়ে যেতে পারে একটি চালনার জন্য 'init' প্রক্রিয়া উত্তরাধিকার সূত্রে প্রাপ্ত হবে (বা অনুরূপ will) তবে প্রক্রিয়া আচরণের এই বিষয়টি জটিল হয়ে উঠতে পারে এবং আমি কেবল এটি সেখানে রেখে যাব ...

আমি একটি পদ্ধতি পছন্দ করি যদি আমি একটি নিয়ন্ত্রণ স্ক্রিপ্ট ব্যবহার করতে না চাই (পরবর্তী বর্ণিত) হ'ল প্রক্রিয়াটি শুরু করতে এবং পরিচালনা করতে 'স্ক্রিন' ইউটিলিটিটি ব্যবহার করা। 'স্ক্রিন' কমান্ডটি বৈশিষ্ট্যগুলিতে পূর্ণ এবং মাস্টার পেতে কিছুটা সময় নিতে পারে। আমি আপনাকে পুরো ব্যাখ্যার জন্য 'স্ক্রিন' ম্যান পৃষ্ঠা পড়তে উত্সাহিত করব। পটভূমিতে একটি প্রক্রিয়া শুরু করার জন্য একটি দ্রুত উদাহরণ হ'ল আদেশটি:

স্ক্রিন-ডি-এম / পাথ / টু / প্রোগ্রাম

এটি একটি 'স্ক্রিন' সেশনের অভ্যন্তরে "/ পাথ / টু / প্রোগ্রাম" শুরু করবে।

আপনি কমান্ডটি দিয়ে আপনার চলমান সেশনটি দেখতে পাবেন:

পর্দা-এলএস

এবং যে কোনও সময় আপনি কমান্ডটি দিয়ে আপনার চলমান প্রোগ্রামের সাথে পুনরায় সংযোগ করতে পারেন:

পর্দা -r

এবং তারপরে এটিকে কেবল একটি ডিগ্রি সেন্টিগ্রেড বা যা কিছু দিয়ে শেষ করুন।

ইচ্ছামত আপনার প্রক্রিয়াটি পুনরায় সংযোগ স্থাপন এবং সংযোগ বিচ্ছিন্ন করতে সক্ষম হওয়ার পাশাপাশি 'স্ক্রিন' আপনার প্রোগ্রামটি যে কোনও স্টাডাউট () ক্যাপচার করবে।


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

নিম্নলিখিত প্রোগ্রামটি "প্রোগ্রামার্টেল" নামে একটি ফাইলে সংরক্ষণ করুন, কমান্ডটি দিয়ে এটি সম্পাদনযোগ্য করুন:

chmod 755 programctl

তারপরে ফাইলটি সম্পাদনা করুন এবং "কোডটি" দিয়ে শুরু হওয়া কেস-বিভাগে আপনার কোড / স্ক্রিপ্ট যুক্ত করুন।

"ডেস্কটপটি" বর্তমান ডিরেক্টরিতে থাকা অনুমান করে সবকিছু ঠিকঠাক হয়ে গেলে আপনি আপনার প্রোগ্রামটি দিয়ে শুরু করতে পারেন:

./pramramctl শুরু

এবং এটি দিয়ে বন্ধ করুন:

। / প্রোগ্রামাগুলি স্টপ

চিয়ার্স।

#!/bin/bash
# Description:  A wrapper script used to stop/start another script.

#--------------------------------------
# Define Global Environment Settings:
#--------------------------------------

# Name and location of a persistent PID file

PIDFILE="/tmp/tmpfile-$LOGNAME.txt"

#--------------------------------------
# Check command line option and run...
# Note that "myscript" should not
# provided by the user.
#--------------------------------------

case $1
in
    myscript)
        # This is where your script would go.
        # If this is a routine 'bash' shell script, you can enter
        # the script below as illustrated in the example.  
        # Or you could simply provide the path and parameters
        # to another script such as /dir/name/command -options

        # Example of an embedded script:

        while true
        do
            # do something over and over...
            sleep 1
        done

        # Example of an external script:

        /usr/local/bin/longrun -x
    ;;

    start)
        # Start your script in the background.
        # (Note that this is a recursive call to the wrapper
        #  itself that effectively runs your script located above.)
        $0 myscript &

        # Save the backgound job process number into a file.
        jobs -p > $PIDFILE

        # Disconnect the job from this shell.
        # (Note that 'disown' command is only in the 'bash' shell.)
        disown %1

        # Print a message indicating the script has been started
        echo "Script has been started..."
    ;;

    stop)
        # Read the process number into the variable called PID
        read PID < $PIDFILE

        # Remove the PIDFILE
        rm -f $PIDFILE

        # Send a 'terminate' signal to process
        kill $PID

        # Print a message indicating the script has been stopped
        echo "Script has been stopped..."
    ;;

    *)
        # Print a "usage" message in case no arguments are supplied
        echo "Usage: $0 start | stop"
    ;;
esac

আপনার প্রস্তাবিত "স্ক্রিন" পদ্ধতিটি চেষ্টা করেছি এবং এটি সুন্দরভাবে কাজ করে। আমি এখনও দ্বিতীয় পদ্ধতিতে চেষ্টা করতে চাই। উত্তরের জন্য ধন্যবাদ.
light94
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.