簡體   English   中英

如何在Python中打開<del>命名管道</ del>字符設備專用文件進行讀寫

[英]How to open <del>named pipe</del>character device special file for reading and writing in Python

我有一個在Linux機器上運行的服務,可以創建一個 命名管道 字符設備特殊文件,我想編寫一個Python3程序,通過編寫文本命令和閱讀文本回復來與服務進行通信 設備。 我沒有該服務的源代碼。

我可以使用os.open(named_pipe_pathname, os.O_RDWR) ,我可以使用os.read(...)os.write(...)來讀取和寫入它,但這很痛苦,因為我必須寫我自己的代碼在字節和字符串之間轉換,我必須編寫自己的readline(...)函數等。

我寧願使用Python3 io對象來讀寫 設備,但我能想到創建一個的方式返回相同的錯誤:

io.UnsupportedOperation: File or stream is not seekable.

例如,如果我嘗試open(pathname, "r+") ,我會得到該消息,如果我嘗試fd=os.open(...)后跟os.fdopen(fd, "r+", ...)我得到相同的消息fd=os.open(...) os.fdopen(fd, "r+", ...)

問:Python3程序在文本中寫入和讀取文本的首選方法是什么? 命名管道 角色設備?


編輯:

哎呀! 我假設我正在處理一個命名管道,因為該服務的文檔將其描述為“管道”,因為它在用戶模式服務運行之前不會出現在文件系統中。 但是,Linux file實用程序說它實際上是一個字符設備特殊文件。

你可以使用pexpect 以下是使用兩個python模塊的示例:

caller.py

import pexpect

proc = pexpect.spawn('python3 backwards.py')
proc.expect(' > ')

while True:

    n = proc.sendline(input('Feed me - '))
    proc.expect(' > ')
    print(proc.before[n+1:].decode())

backwards.py

x = ''

while True:
    x = input(x[::-1] + ' > ')

說明

caller.py正在使用“Pseudo-TTY設備”與backwards.py交談。 我們使用expect (以及before屬性)提供sendline輸入和捕獲輸入。

出現該問題是因為試圖使用io.open在讀寫模式隱含地嘗試包裹在底層文件io.BufferedRandom (其然后包裹在io.TextIOWrapper如果在文本模式下),其中假定基礎文件是不是只讀/ write,但隨機訪問,它基於此需要自由(尋求隱式)。 有一個單獨的類io.BufferedRWPair ,用於讀/寫管道(docstring特別提到它用於套接字和雙向管道)。

您可以通過逐層手動包裝來模仿io.open的效果,以產生相同的最終結果。 具體來說,對於文本模式包裝器,您可以執行以下操作:

rawf = io.FileIO(named_pipe_pathname, mode="rb+")
with io.TextIOWrapper(io.BufferedRWPair(rawf, rawf), encoding='utf-8', write_through=True) as txtf:
    del rawf   # Remove separate reference to rawf; txtf manages lifetime now
    # Example use that works (but is terrible form, since communicating with
    # oneself without threading, select module, etc., is highly likely to deadlock)
    # It works for this super-simple case; presumably you have some parallel real code
    txtf.write("abcé\n")
    txtf.flush()
    print(txtf.readline(), flush=True)

我相信當txtf關閉時,這將關閉rawf兩次,但幸運的是,雙關閉在這里是無害的(第二次close什么也沒做,意識到它已經關閉)。

看起來你需要為閱讀和寫入創建單獨的句柄:打開讀/寫只需要一個搜索方法。 我無法弄清楚如何超時讀取,所以最好添加一個開啟器(參見io.open的docstring),以非阻塞模式打開閱讀器。 我在名為/tmp/test_pipe的命名管道上設置了一個簡單的echo服務:

In [1]: import io
In [2]: import os
In [3]: nonblockingOpener = lambda name, flags:os.open(name, flags|os.O_NONBLOCK)
In [4]: reader = io.open('/tmp/test_pipe', 'r', opener = nonblockingOpener)
In [5]: writer = io.open('/tmp/test_pipe', 'w')
In [6]: writer.write('Hi have a line\n')
In [7]: writer.flush()
In [8]: reader.readline()
Out[8]: 'You said: Hi have a line\n'
In [9]: reader.readline()
''

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM