سؤال

عادةً، يقوم المرء بإيقاف تشغيل Apache Tomcat عن طريق تشغيل ملف shutdown.sh البرنامج النصي (أو ملف دفعي).في بعض الحالات، مثل عندما تستضيف حاوية الويب الخاصة بـ Tomcat تطبيق ويب يقوم ببعض الأشياء المجنونة باستخدام سلاسل العمليات المتعددة، وتشغيله shutdown.sh يغلق برشاقة بعض أجزاء من Tomcat (حيث أستطيع رؤية المزيد من الذاكرة المتوفرة تعود إلى النظام)، لكن عملية Tomcat تستمر في العمل.

أحاول كتابة نص بايثون بسيط:

  1. المكالمات shutdown.sh
  2. أشواط ps -aef | grep tomcat للعثور على أي عملية مع Tomcat المشار إليها
  3. إذا كان ذلك ممكنا، يقتل العملية مع kill -9 <PID>

إليك ما حصلت عليه حتى الآن (كنموذج أولي - أنا جديد تمامًا على لغة Python راجع للشغل):

#!/usr/bin/python

# Imports
import sys
import subprocess

# Load from imported module.
if __init__ == "__main__":
    main()

# Main entry point.
def main():
    # Shutdown Tomcat
    shutdownCmd = "sh ${TOMCAT_HOME}/bin/shutdown.sh"
    subprocess.call([shutdownCmd], shell=true)

    # Check for PID
    grepCmd = "ps -aef | grep tomcat"
    grepResults = subprocess.call([grepCmd], shell=true)

    if(grepResult.length > 1):
        # Get PID and kill it.
        pid = ???
        killPidCmd = "kill -9 $pid"
        subprocess.call([killPidCmd], shell=true)

    # Exit.
    sys.exit()

أنا أعاني مع الجزء الأوسط - مع الحصول على grep النتائج، والتحقق لمعرفة ما إذا كان حجمها أكبر من 1 (منذ grep تُرجع دائمًا مرجعًا إلى نفسها، وسيتم إرجاع نتيجة واحدة على الأقل دائمًا، كما أعتقد)، ثم تحليل PID الذي تم إرجاعه وتمريره إلى killPidCmd.شكرا لك مقدما!

هل كانت مفيدة؟

المحلول

تحتاج إلى استبدال grepResults = subprocess.call([grepCmd], shell=true) مع grepResults = subprocess.check_output([grepCmd], shell=true) إذا كنت تريد حفظ نتائج الأمر في grepResults.ثم يمكنك استخدام التقسيم لتحويل ذلك إلى مصفوفة وسيكون العنصر الثاني في المصفوفة هو pid: pid = int(grepResults.split()[1])'

هذا لن يؤدي إلا إلى قتل العملية الأولى.لا يقتل جميع العمليات إذا كان هناك أكثر من واحدة مفتوحة.للقيام بذلك عليك أن تكتب:

grepResults = subprocess.check_output([grepCmd], shell=true).split()
for i in range(1, len(grepResults), 9):
  pid = grepResults[i]
  killPidCmd = "kill -9 " + pid
  subprocess.call([killPidCmd], shell=true)

نصائح أخرى

يمكنك إضافة "c" إلى ps بحيث تتم طباعة الأمر فقط وليس الوسائط.هذا من شأنه أن يمنع الاستيلاء من مطابقة نفسه.

لست متأكدًا مما إذا كان Tomcat سيظهر كتطبيق جافا، لذلك قد لا ينجح هذا.

ملاحظة:حصلت على هذا من جوجل:"grep يتضمن الذات" وكانت الضربة الأولى تحتوي على هذا الحل.

يحرر:خطأي!طيب شيء من هذا القبيل بعد ذلك؟

p = subprocess.Popen(["ps caux | grep tomcat"], shell=True,stdout=subprocess.PIPE)
out, err = p.communicate()
out.split()[1] #<-- checkout the contents of this variable, it'll have your pid!

في الأساس، سيكون لـ "out" مخرجات البرنامج كسلسلة يمكنك قراءتها/معالجتها

إنشاء عمليات فرعية للتشغيل ps وسلسلة تطابق الإخراج مع grep ليس ضروري.تتمتع Python بمعالجة رائعة للسلسلة "مخبأة" ويكشف Linux عن جميع المعلومات المطلوبة في /proc.جبل procfs هو المكان الذي تحصل فيه أدوات سطر الأوامر المساعدة على هذه المعلومات.ومن الأفضل أن تذهب مباشرة إلى المصدر.

import os

SIGTERM = 15

def pidof(image):
    matching_proc_images = []
    for pid in [dir for dir in os.listdir('/proc') if dir.isdigit()]:
        lines = open('/proc/%s/status' % pid, 'r').readlines()
        for line in lines:
            if line.startswith('Name:'):
                name = line.split(':', 1)[1].strip()
                if name == image:
                    matching_proc_images.append(int(pid))

    return matching_proc_images


for pid in pidof('tomcat'): os.kill(pid, SIGTERM)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top