- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
显然这几乎是“Bad pipe filedescriptor when reading from stdin in python - Stack Overflow”的副本;但是,我认为这种情况稍微复杂一些(并且它不是特定于 Windows 的,因为该线程的结论是)。
我目前正在尝试使用 Python 中的一个简单脚本进行试验:我想为脚本提供输入 - 通过命令行参数;或通过“管道”将字符串输入此脚本 - 并让脚本使用 curses
终端界面显示此输入字符串。
下面给出了完整的脚本,这里称为 testcurses.py
。问题是,每当我尝试实际的管道时,它似乎会弄乱标准输入,并且 curses
窗口永远不会显示。这是一个终端输出:
## CASE 1: THROUGH COMMAND LINE ARGUMENT (arg being stdin):
##
$ ./testcurses.py -
['-'] 1
stdout/stdin (obj): <open file '<stdout>', mode 'w' at 0xb77dc078> <open file '<stdin>', mode 'r' at 0xb77dc020>
stdout/stdin (fn): 1 0
env(TERM): xterm xterm
stdin_termios_attr [27906, 5, 1215, 35387, 15, 15, ['\x03', ... '\x00']]
stdout_termios_attr [27906, 5, 1215, 35387, 15, 15, ['\x03', ... '\x00']]
opening -
obj <open file '<stdin>', mode 'r' at 0xb77dc020>
TYPING blabla HERE
wr TYPING blabla HERE
at end
before curses TYPING blabla HERE
#
# AT THIS POINT:
# in this case, curses window is shown, with the text 'TYPING blabla HERE'
# ################
## CASE 2: THROUGH PIPE
##
## NOTE I get the same output, even if I try syntax as in SO1057638, like:
## python -c "print 'TYPING blabla HERE'" | python testcurses.py -
##
$ echo "TYPING blabla HERE" | ./testcurses.py -
['-'] 1
stdout/stdin (obj): <open file '<stdout>', mode 'w' at 0xb774a078> <open file '<stdin>', mode 'r' at 0xb774a020>
stdout/stdin (fn): 1 0
env(TERM): xterm xterm
stdin_termios_attr <class 'termios.error'>::(22, 'Invalid argument')
stdout_termios_attr [27906, 5, 1215, 35387, 15, 15, ['\x03', '\x1c', '\x7f', '\x15', '\x04', '\x00', '\x01', '\xff', '\x11', '\x13', '\x1a', '\xff', '\x12', '\x0f', '\x17', '\x16', '\xff', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00']]
opening -
obj <open file '<stdin>', mode 'r' at 0xb774a020>
wr TYPING blabla HERE
at end
before curses TYPING blabla HERE
#
# AT THIS POINT:
# script simply exits, nothing is shown
# ################
据我所知,问题是:- 每当我们将字符串通过管道传输到 Python 脚本时,Python 脚本都会丢失对 terminal 作为 stdin
的引用,并注意到被替换的 stdin
不再是 termios
结构 - 因为 stdin
不再是终端,curses.initscr( )
立即退出而不渲染任何东西。
所以,我的问题是 - 简而言之:我能否以某种方式实现语法 echo "blabla"| ./testcurses.py -
最终在 curses
中显示管道字符串?更具体地说:是否可以从 Python 脚本中检索对调用终端的 stdin
的引用,即使该脚本正在被“管道”传输到?
提前感谢任何指点,
干杯!
PS: testcurses.py
脚本:
#!/usr/bin/env python
# http://www.tuxradar.com/content/code-project-build-ncurses-ui-python
# http://diveintopython.net/scripts_and_streams/stdin_stdout_stderr.html
# http://bytes.com/topic/python/answers/42283-curses-disable-readline-replace-stdin
#
# NOTE: press 'q' to exit curses - Ctrl-C will screw up yer terminal
# ./testcurses.py "blabla" # works fine (curseswin shows)
# ./testcurses.py - # works fine, (type, enter, curseswins shows):
# echo "blabla" | ./testcurses.py "sdsd" # fails to raise curses window
#
# NOTE: when without pipe: termios.tcgetattr(sys.__stdin__.fileno()): [27906, 5, 1215, 35387, 15, 15, ['\x03',
# NOTE: when with pipe | : termios.tcgetattr(sys.__stdin__.fileno()): termios.error: (22, 'Invalid argument')
import curses
import sys
import os
import atexit
import termios
def openAnything(source):
"""URI, filename, or string --> stream
http://diveintopython.net/xml_processing/index.html#kgp.divein
This function lets you define parsers that take any input source
(URL, pathname to local or network file, or actual data as a string)
and deal with it in a uniform manner. Returned object is guaranteed
to have all the basic stdio read methods (read, readline, readlines).
Just .close() the object when you're done with it.
"""
if hasattr(source, "read"):
return source
if source == '-':
import sys
return sys.stdin
# try to open with urllib (if source is http, ftp, or file URL)
import urllib
try:
return urllib.urlopen(source)
except (IOError, OSError):
pass
# try to open with native open function (if source is pathname)
try:
return open(source)
except (IOError, OSError):
pass
# treat source as string
import StringIO
return StringIO.StringIO(str(source))
def main(argv):
print argv, len(argv)
print "stdout/stdin (obj):", sys.__stdout__, sys.__stdin__
print "stdout/stdin (fn):", sys.__stdout__.fileno(), sys.__stdin__.fileno()
print "env(TERM):", os.environ.get('TERM'), os.environ.get("TERM", "unknown")
stdin_term_attr = 0
stdout_term_attr = 0
try:
stdin_term_attr = termios.tcgetattr(sys.__stdin__.fileno())
except:
stdin_term_attr = "%s::%s" % (sys.exc_info()[0], sys.exc_info()[1])
try:
stdout_term_attr = termios.tcgetattr(sys.__stdout__.fileno())
except:
stdout_term_attr = `sys.exc_info()[0]` + "::" + `sys.exc_info()[1]`
print "stdin_termios_attr", stdin_term_attr
print "stdout_termios_attr", stdout_term_attr
fname = ""
if len(argv):
fname = argv[0]
writetxt = "Python curses in action!"
if fname != "":
print "opening", fname
fobj = openAnything(fname)
print "obj", fobj
writetxt = fobj.readline(100) # max 100 chars read
print "wr", writetxt
fobj.close()
print "at end"
sys.stderr.write("before ")
print "curses", writetxt
try:
myscreen = curses.initscr()
#~ atexit.register(curses.endwin)
except:
print "Unexpected error:", sys.exc_info()[0]
sys.stderr.write("after initscr") # this won't show, even if curseswin runs fine
myscreen.border(0)
myscreen.addstr(12, 25, writetxt)
myscreen.refresh()
myscreen.getch()
#~ curses.endwin()
atexit.register(curses.endwin)
sys.stderr.write("after end") # this won't show, even if curseswin runs fine
# run the main function - with arguments passed to script:
if __name__ == "__main__":
main(sys.argv[1:])
sys.stderr.write("after main1") # these won't show either,
sys.stderr.write("after main2") # (.. even if curseswin runs fine ..)
最佳答案
The problem is that whenever I try the actual piping, that seems to mess up stdin, and the curses window never shows. [...snip...]As far as I can see, the issue is: - whenever we pipe strings into the Python script, the Python script loses the reference to the terminal as stdin, and notices that the replaced stdin is not a termios structure anymore - and since stdin is no longer a terminal, curses.initscr() exits immediately without rendering anything.
实际上,curses 窗口确实显示了,但由于您勇敢的新 stdin 上没有更多输入,myscreen.getch()
立即返回。所以它与 curses 测试 stdin 是否为终端无关。
因此,如果您想使用 myscreen.getch()
和其他 curses 输入函数,您将不得不重新打开您的终端。在 Linux 和 *nix 系统上,通常有一个名为 /dev/tty
的设备,它指的是当前终端。所以你可以这样做:
f=open("/dev/tty")
os.dup2(f.fileno(), 0)
在调用 myscreen.getch()
之前。
关于python - Linux:通过管道传输到 Python (ncurses) 脚本、stdin 和 termios,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3999114/
我正在使用 Python 3.7,我需要 import termios屏蔽密码输入。但我无法在 https://pypi.org/ 上找到它 import sys, tty, termios Trac
我想要实现的目标:我想设置自定义 baud rate一些值 tty* -喜欢UART -映射终端。 方法:目前我发现的唯一方法是使用 struct termios2结构位于 header (如前所述
我需要通过 UART 连接与某个传感器“对话”。使用 termios 一切工作都没有问题,我能够与它进行持续的通信 - 多次写入和读取。 但是,如果我在此通信期间的任何时间使用 fopen() 或 o
在更改终端设置的代码中(它嵌入了 python,后者又使用一些终端操作模块),在我通过 Ctrl-\向进程发送 SIGQUIT 退出后,更改的状态仍然存在。 在启动时保存终端设置,然后注册将恢复这些设
我正在开发一个 C 程序,用于监听在 ARM Linux 嵌入式设备上运行的串口。 其他数据集工作正常,但当我发送一组特定数据时,数据集的开头总是被截断。被截断的内容如下(目标上运行的slsniff程
我是 C 和驱动程序编程的新手。目前,我正在编写一个用户空间驱动程序,以使用 Debian 通过 USB 与 RS232 进行通信。在研究时,我遇到了以下代码。 tty.c_cflag &=
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 5 个月前关闭。 Improve t
newattr.c_lflag &= ~(ICANON|ECHO); 这里是 c_lflag 的新值已经设置好了。但我不明白这是什么意思&= ~ | 是什么?表示介于 ICANON 之间和ECHO ?
基本上,如果我写: struct termios raw; tcgetattr(STDIN_FILENO, &raw); raw.c_lflag &= ~(ECHO); tcsetattr(STDIN
我有一个设置为 ~(ICANON) 模式的终端,想知道如何使用为退格键获得的数据(即 ^?),以便我可以将 putchar('\b') 发送到控制台后退一格。 编辑: struct termios n
我遇到的问题是,当您按下箭头键时,您检测到 3 个输入并且 while 循环执行了 3 次,实际上字符串 PRINT OF DEBUG 的打印发生了 3 次。为什么?我希望当您按下箭头键时,循环会执行
测试.c... #include #include int main() { printf("%x\n",B600); } 在我的系统上,这会打印“8”。 gcc -M test.c 显示
使用非规范输入处理,我正在使用带有“DB9-to-USB”电缆的 Xbee 接口(interface) XBIB-R-Dev 读取发送到 Xbee S2B Pro (ZB) 的串行数据。我正在使用 h
我们整个上午都在为这个问题苦苦思索。我们在嵌入式 linux 设备和 Ubuntu 机器之间设置了一些串行线路。我们的读取被搞砸了,因为我们的代码通常返回两个(有时更多,有时恰好一个)消息读取,而不是
我想获取终端的大小。我正在使用此功能: import sys, struct, fcntl, termios s = struct.pack('HHHH', 0, 0, 0, 0) t = fcntl
我需要使用串行端口进行聊天。我通过 socat 模拟 pty: socat -d -d PTY PTY 接下来我写了一个小演示。这就是我初始化 termios 结构的方式: int tty_f
我正在使用 termios.h 与 USB 适配器进行通信。我想在断开加密狗时关闭文件描述符。有没有办法做到这一点。我知道这是为了f.e.对于 TCP/IP 连接,如果对方关闭连接,您将收到 EOF。
我需要通过 USB 虚拟串行设备与硬件进行通信。我所需要的只是使用正确的 UART 设置来快速地来回传递原始字节,我不想使用终端。使用 termios 的概念验证软件没有配置正确的位,并且除非我在运行
我正在 Linux 中制作一个 C++ 串行类。我正在尝试在收到传入数据时注册一个事件。 我正在研究 Olimex Lime2 板。gcc 版本 4.6.3 (Debian 4.6.3-14) 这是我
我在(资源受限的)嵌入式 Linux 平台(C 语言)中使用 Termios 从各种 tty 外围设备 (CP2102 USB-UART) 发送命令和接收数据。显然有多种方法可以做到这一点,而且很多方
我是一名优秀的程序员,十分优秀!