[英]Using file descriptors to communicate between processes
我有以下python代碼:
import pty
import subprocess
os=subprocess.os
from subprocess import PIPE
import time
import resource
pipe=subprocess.Popen(["cat"], stdin=PIPE, stdout=PIPE, stderr=PIPE, \
close_fds=True)
skip=[f.fileno() for f in (pipe.stdin, pipe.stdout, pipe.stderr)]
pid, child_fd = pty.fork()
if(pid==0):
max_fd=resource.getrlimit(resource.RLIMIT_NOFILE)[0]
fd=3
while fd<max_fd:
if(fd not in skip):
try:
os.close(fd)
except OSError:
pass
fd+=1
enviroment=os.environ.copy()
enviroment.update({"FD": str(pipe.stdin.fileno())})
os.execvpe("zsh", ["-i", "-s"], enviroment)
else:
os.write(child_fd, "echo a >&$FD\n")
time.sleep(1)
print pipe.stdout.read(2)
我如何重寫它,使其不使用Popen
和cat
? 我需要一種方法,該方法可以從運行在交互式外殼程序中的外殼程序功能傳遞數據,而不會與其他功能創建的數據混合(因此,我無法使用stdout或stderr)。
好的,我想我已經解決了您的問題,並看到了您可以采用的兩種不同方法。
如果你絕對要提供孩子過程中的外殼,一個已經打開的文件描述符,那么你就可以更換Popen()
的cat
通過調用os.pipe()
這將為您提供一對連接的真實文件描述符(不是Python file
對象)。 可以從第一個文件描述符讀取寫入第二個文件描述符的所有內容,從而取代由陪審團操縱的cat
-pipe。 (盡管說“ cat-pipe”很有趣...)。 如果需要雙向對,也可以使用套接字對( socket.socketpair()
)來達到相同的目的。
另外,您可以使用命名管道(aka FIFO)進一步簡化生活。 如果您不熟悉該功能,則命名管道是位於文件系統名稱空間中的單向管道。 os.mkfifo()
函數將在文件系統上創建管道。 然后,您可以在主要過程中打開管道以進行讀取,並從shell子進程中將其打開以進行寫入/直接輸出。 這應該簡化您的代碼,並打開使用Pexpect之類的現有庫與外殼進行交互的選項。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.