Bối cảnh:Tại sao Pexpect không liên tục treo (không phát hiện EOF) sau khi thực hiện các lệnh nhất định?
Tôi có một số mã được viết bằng pexpect
, có nhiệm vụ cung cấp cho "sống" đầu ra của một lệnh. I E. in một cái gì đó ra khi một lệnh tạo ra một số đầu ra, hoặc ngay sau đó, thay vì đợi cho đến khi lệnh hoàn thành và sau đó tương tác với đầu ra của nó.
Tất cả những gì tôi đang làm là bắt đầu và dừng dịch vụ. Tôi làm điều này bằng spawn
ing quá trình này, và sau đó xuất ra mỗi dòng như nó được in, như vậy:
def watch(process):
output = ""
while True:
try:
line = process.read_nonblocking(timeout = -1)
print(line, end ="")
output += line
except pexpect.EOF:
break
del process
return output
while True:
print("IN 1")
process = pexpect.spawn("service",["zend-server", "stop"], timeout = None)
watch(process)
print("OUT 1")
print("IN 2")
process = pexpect.spawn("service",["zend-server", "start"], timeout = None)
watch(process)
print("OUT 2")
Mã này nên chỉ loop dịch vụ: bắt đầu nó và ngăn chặn nó hơn và hơn, in đầu ra của bắt đầu/dừng lại khi nó đi. Nó in đầu ra tốt. Tuy nhiên, nó cuối cùng bị treo ngay trước "OUT 2". Tôi có thể xem đầu ra và xem lệnh gọi service
ngừng thực thi. Tuy nhiên, hàm watch
không bao giờ tăng EOF và thoát.
Điều này không xảy ra với mọi dịch vụ. Một số dịch vụ lặp vô thời hạn. Tuy nhiên, zend-server
, cùng với một vài lệnh không có liên quan khác, không liên tục theo cùng một cách.
Bởi "cuối cùng bị treo", tôi có nghĩa là nó bắt đầu/dừng dịch vụ một vài (biến trên mỗi lần chạy) lần và bị treo. Nó thường nướu răng sau 4-6, mặc dù không bao giờ vào cuộc gọi đầu tiên - luôn luôn ít nhất là trên thứ hai (do đó tuyên bố del
; Tôi figured tôi muốn chơi nó an toàn).
Python 2.6.6, CentOS (64) 6.3, Pexpect 2,3-6, FWIW
Câu hỏi:
Tại sao pexpect
treo trên lệnh nhất định? Tôi nên giải quyết vấn đề này như thế nào? Sử dụng thời gian chờ không phải là giải pháp khả thi vì một số lệnh này thực sự có thể chạy trong một thời gian dài tùy ý. service zend-server stop
chỉ là một trong những tôi đã chọn cho một ví dụ bởi vì nó không mất nhiều thời gian, và tôi có thể quan sát nó hoàn thành.
Những gì tôi đã thử:
tôi đã cố gắng thay thế các phương pháp watch
với những điều sau đây, trong đó sử dụng expect('\n')
, nhưng kết quả đều giống nhau: một số biến của khởi động lại, và sau đó một treo cuối cùng .
Tôi cũng có thể thêm pexpect.EOF
vào mảng là expect
ed cùng với \n
và xử lý giá trị trả về để thoát ra khỏi vòng lặp, nó vẫn bị treo ở cùng một vị trí.
def watch2(process):
output = ""
done = False
while True:
try:
if not process.isalive():
line = process.readline()
done = True
else:
process.expect(['\n'])
line = process.before
print(line)
output += line
if done:
raise pexpect.EOF(0)
except pexpect.EOF:
break
del process
return output
Tại sao bạn sử dụng 'pexpect' khi bạn không làm bất kỳ điều gì tương tác với quy trình con? 'subprocess' từ stdlib sẽ đủ nếu bạn chỉ quan tâm đến đầu ra. –
Đó là một ví dụ đơn giản. Trong phiên bản sản xuất, có các cuộc gọi đến 'mong đợi', nhưng ví dụ bị loại bỏ tôi gửi không hoạt động chính xác. –
Tôi không thể sao chép sự cố của bạn bằng mã này. Tôi không chắc chắn mã là vấn đề.Có lẽ bạn chỉ không nhận được bất kỳ đầu ra từ máy chủ zend? – aychedee