2012-10-23 18 views
8

में काम करते समय पाइथन में Ctrl-C कीबोर्ड को बाधित करें, मैं कुछ स्क्रिप्ट्स (जिस कंपनी में मैं काम करता हूं) पर काम कर रहा हूं जो किसी घटना के दौरान कोड के टुकड़े को आग लगाने के लिए हाइपरवाइजर में लोड/अनलोड किया जाता है। वास्तव में एक स्क्रिप्ट को अनलोड करने का एकमात्र तरीका है Ctrl - सी। मैं पाइथन में एक फ़ंक्शन लिख रहा हूं जो प्रक्रिया को स्वचालित करता हैलिनक्स

जैसे ही यह प्रोग्राम के आउटपुट में "done" स्ट्रिंग को देखता है, इसे vprobe को मारना चाहिए। मैं subprocess.Popen उपयोग कर रहा हूँ आदेश पर अमल करने के लिए:

lineList = buff.readlines() 
cmd = "vprobe /vprobe/myhello.emt" 
p = subprocess.Popen(args = cmd, shell=True,stdout = buff, universal_newlines = True,preexec_fn=os.setsid) 
while not re.search("done",lineList[-1]): 
     print "waiting" 
os.kill(p.pid,signal.CTRL_C_EVENT) 

आप देख सकते हैं, मैं buff फ़ाइल वर्णनकर्ता पढ़ने + लिखने मोड में खोला में उत्पादन लिख रहा हूँ। मैं आखिरी पंक्ति की जांच करता हूं; अगर इसमें 'done' है, तो मैं इसे मार डालता हूं। दुर्भाग्य से, CTRL_C_EVENT केवल विंडोज के लिए मान्य है। लिनक्स के लिए मैं क्या कर सकता हूं?

+3

FYI करें उदाहरण के लिए: 'एक निरंतर तार के साथ re.search' बेहतर रूप में' व्यक्त किया जा सकता है, जबकि lineList में नहीं 'पूर्ण' [-1]: ... ' – nneonneo

+0

हाँ, आप सही हैं। धन्यवाद। –

उत्तर

8

मुझे लगता है कि आप केवल लिनक्स समकक्ष, signal.SIGINT (इंटरप्ट सिग्नल) भेज सकते हैं।

(संपादित करें: मुझे उपप्रोसेस को नियंत्रित करने के लिए इस रणनीति के उपयोग को हतोत्साहित करने के लिए यहां कुछ उपयोग किया जाता था, लेकिन अधिक सावधानीपूर्वक पढ़ने पर ऐसा लगता है कि आप पहले से ही तय कर चुके हैं कि आपको इस विशिष्ट मामले में नियंत्रण-सी की आवश्यकता है ... तो, SIGINT इसे करना चाहिए।)

+0

हे एंड्रयू। जवाब के लिए धन्यवाद। लेकिन वास्तव में, सिगिनट केवल उपप्रोसेस समारोह को मारता है जबकि vprobe इसे निष्पादन जारी रखता है। क्या आपको यह भी पता है कि उसे कैसे मारना है? धन्यवाद –

+1

अच्छा, अगर यह विंडोज पर काम करता है, तो उम्मीद है कि इसका मतलब है कि सिग्नल सही जगह पर जा रहा है। तो, कुछ मजबूत कोशिश करें। SIGTERM को आज़माएं, और यदि यह काम नहीं करता है, तो सिगकेएलएल। अगर सिगिल काम नहीं करता है, तो कुछ भी नहीं होगा - आपको सबप्रोसेस को पूरी तरह से संभालने के विभिन्न तरीकों को देखना होगा। –

+0

क्या आपने 'पॉपन ([' vprobe ',' /vprobe/myhello.emt '], shell = गलत, ...) '? @Core_Dumped – alk

1

शायद मैं कुछ गलत समझ सकता हूं, लेकिन जिस तरह से आप वांछित परिणाम प्राप्त करना मुश्किल है।

जो भी buff है, आप इसे पहले पूछताछ करते हैं, फिर इसे Popen() के संदर्भ में उपयोग करें और फिर आप उम्मीद करते हैं कि maciv lineList स्वयं भर जाता है।

क्या आप शायद चाहते हैं की तरह

logfile = open("mylogfile", "a") 
p = subprocess.Popen(['vprobe', '/vprobe/myhello.emt'], stdout=subprocess.PIPE, buff, universal_newlines=True, preexec_fn=os.setsid) 
for line in p.stdout: 
    logfile.write(line) 
    if re.search("done", line): 
     break 
    print "waiting" 
os.kill(p.pid, signal.CTRL_C_EVENT) 

कुछ यह आपको एक पाइप अंत अपने vprobe स्क्रिप्ट के द्वारा खिलाया जो आप linewise पढ़ा और पाया उत्पादन पर उचित रूप से कार्य कर सकते हैं देता है।

+0

यह लगभग वही है जो मैं करना चाहता हूं, सिवाय इसके कि मैं चाहता हूं कि आउटपुट कुछ फाइलों में भी मुद्रित हो (साथ ही जांच उद्देश्यों के लिए पीआईपीई में शामिल होने के साथ)। मैं उसे कैसे कर सकता हूँ? (मुझे उम्मीद है कि मैं इस समय व्याकरणिक रूप से सही हूं :)) –

+0

मैंने ऐसा करने का तरीका प्रदान करने के लिए अपना उत्तर संपादित किया। – glglgl

+0

उपर्युक्त कोड अच्छी तरह से अच्छा लगता है लेकिन जब मैं ऑब्जेक्ट पी की विशेषता के रूप में stdout का उपयोग करता हूं, तो यह मुझे टूटी हुई पीआईपीई त्रुटि देता है। –

3

लिनक्स में, Ctrl-C कीबोर्ड इंटरप्ट को Popen.send_signal (signal.SIGINT) फ़ंक्शन का उपयोग करके प्रक्रिया में प्रोग्रामेटिक रूप से भेजा जा सकता है।

import subprocess 
import signal 

.. 
process = subprocess.Popen(..) 
.. 
process.send_signal(signal.SIGINT) 
.. 

.. अवरुद्ध आदेश के लिए Popen.communicate() का उपयोग न करें

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^