शीर्षक के हिस्से पर छूने वाले बहुत सारे विषय हैं, लेकिन कुछ भी नहीं जो पूरी चीज को पूरा करता है। मैं रिमोट सर्वर पर कमांड दबा रहा हूं और लंबे निष्पादन समय के बाद पूर्ण आउटपुट की आवश्यकता है, 5 मिनट या उससे भी ज्यादा कहें। चैनल का उपयोग करके मैं एक टाइमआउट सेट करने में सक्षम था, लेकिन जब मैंने स्टडआउट वापस पढ़ा तो मुझे आउटपुट का केवल एक छोटा सा हिस्सा मिला। समाधान channel.exit_status_ready() के लिए प्रतीक्षा करना प्रतीत होता था। यह एक सफल कॉल पर काम करता था, लेकिन एक असफल कॉल चैनल टाइमआउट को कभी भी ट्रिगर नहीं करेगा। दस्तावेज़ों की समीक्षा करने के बाद, मैं सिद्धांतित करता हूं क्योंकि टाइमआउट केवल पढ़ने के लिए काम करता है, और बाहर निकलने की स्थिति की प्रतीक्षा करने योग्य नहीं है। यहां वह प्रयास है:लंबे निष्पादन के साथ पायथन पैरामीको टाइमआउट, पूर्ण आउटपुट
channel = ssh.get_transport().open_session()
channel.settimeout(timeout)
channel.exec_command(cmd) # return on this is not reliable
while True:
try:
if channel.exit_status_ready():
if channel.recv_ready(): # so use recv instead...
output = channel.recv(1048576)
break
if channel.recv_stderr_ready(): # then check error
error = channel.recv_stderr(1048576)
break
except socket.timeout:
print("SSH channel timeout exceeded.")
break
except Exception:
traceback.print_exc()
break
सुंदर, है ना? इच्छा है कि यह काम किया।
समाधान पर मेरा पहला प्रयास टाइमटाइम() शुरू करने के लिए था, फिर स्टार्ट-टाइम.टाइम()> टाइमआउट देखें। यह सीधा लगता है, लेकिन मेरे वर्तमान संस्करण में, मैं एक निश्चित टाइमआउट के साथ आउटपुट - टाइम.टाइम() शुरू करता हूं जो ब्रेक को ट्रिगर करना चाहिए ... और अंतर को देखें जो बिना किसी ब्रेक के टाइमआउट को दोगुना और तीन गुना करें। अंतरिक्ष को बचाने के लिए, मैं अपने तीसरे प्रयास का उल्लेख करूंगा, जिसे मैंने इस के साथ बढ़ाया है। मैंने यहां आउटपुट का इंतजार करने के लिए select.select का उपयोग करने के बारे में पढ़ा है, और दस्तावेज में नोट किया है कि वहां एक टाइमआउट भी है। जैसा कि आप नीचे दिए गए कोड से देखेंगे, मैंने सभी तीन तरीकों को मिश्रित किया है - चैनल टाइमआउट, टाइम.टाइम टाइमआउट, और टाइमआउट का चयन करें - फिर भी प्रक्रिया को मारना है।
channel = ssh.get_transport().open_session()
channel.settimeout(timeout)
channel.exec_command(cmd) # return on this is not reliable
print("{0}".format(cmd))
start = time.time()
while True:
try:
rlist, wlist, elist = select([channel], [], [],
float(timeout))
print("{0}, {1}, {2}".format(rlist, wlist, elist))
if rlist is not None and len(rlist) > 0:
if channel.exit_status_ready():
if channel.recv_ready(): # so use recv instead...
output = channel.recv(1048576)
break
elif elist is not None and len(elist) > 0:
if channel.recv_stderr_ready(): # then check error
error = channel.recv_stderr(1048576)
break
print("{0} - {1} = {2}".format(
time.time(), start, time.time() - start))
if time.time() - start > timeout:
break
except socket.timeout:
print("SSH channel timeout exceeded.")
break
except Exception:
traceback.print_exc()
break
यहां कुछ सामान्य उत्पादन है: - शुरू = (
[<paramiko.Channel 3 (open) window=515488 -> <paramiko.Transport at 0x888414cL (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>], [], []
1352494558.42 - 1352494554.69 = 3.73274183273
शीर्ष पंक्ति [rlist, wlist, elist] चयन से, लब्बोलुआब यह time.time() है यहाँ frankencode है time.time() - शुरू)। मुझे इस दौड़ को पुनरावृत्ति की गिनती करके और 1000 बार लूप करने के बाद प्रयास के नीचे तोड़ने के लिए मिला। नमूना चलाने पर टाइमआउट 3 पर सेट किया गया था। जो साबित करता है कि हम कोशिश करते हैं, लेकिन जाहिर है, तीन तरीकों में से कोई भी काम नहीं करना चाहिए।
अगर मैंने मूल रूप से कुछ गलत समझा है तो कोड में चिपकने के लिए स्वतंत्र महसूस करें। मैं इसके लिए उबेर-पायथनिक होना चाहता हूं और अभी भी सीख रहा हूं।
मेरा शोध एक ही दिशा में भाग गया, लेकिन मुझे "ValueError: सिग्नल केवल मुख्य धागे में काम करता है", हालांकि मैं जानबूझ कर अपने कोड में धागे का उपयोग नहीं कर रहा हूं। या तो कुछ मॉड्यूल प्रक्रिया को फोर्क कर रहा है या यह एक बग है। विचार? – user1772459
हाँ मुझे एहसास हुआ कि बहुत पाइथन केवल मुख्य धागे में सिग्नल का समर्थन करता है। अगर आपको वह संदेश मिलता है, तो मुझे लगता है कि कुछ बिंदु पर धागे के कुछ स्पंज होते हैं। –