来自带有管道的 termios 的“设备 ioctl 不适当”

问题描述 投票:0回答:2

我昨天在做一个项目,遇到了一个以前没有遇到过的问题。我当前正在使用 argparse 来请求输入文件名,并且我正在添加对通过 stdin 将文件通过管道传输到我的程序的支持。我已经完成所有设置并正常工作,除了每当我将文件通过管道传输到程序时都会遇到的 termios 问题,我想知道是否有人知道解决方案。我得到的确切错误是

    old_settings = self.termios.tcgetattr(fd)
termios.error: (25, 'Inappropriate ioctl for device')

这具体来自 getkey 模块,因为我需要一些用于非阻塞输入的东西(请随时告诉我更好的选择)。我假设它发生是因为它的标准 I/O 流由于管道而没有连接到终端,但我不知道是否有办法可以真正解决这个问题,而且我真的找不到任何解决方案堆栈溢出或谷歌。这是一个最小的可重现示例:

# Assuming filename is test.py, running
# python3 test.py
# works, but running
# cat test.py | python3 test.py
# or
# python3 test.py < test.py
# results in an error
import sys
import termios

termios.tcgetattr(sys.stdin.fileno())
python pipe stdin ioctl termios
2个回答
4
投票

我想出了一个使用

pty
模块的解决方案,这是我之前不知道的。我给出的示例可以通过使用
pty.fork()
将子级连接到新的伪终端来修复。这个程序似乎有效:

import pty
import sys, termios

pid = pty.fork()
if not pid:
    # is child
    termios.tcgetattr(sys.stdin.fileno())

我还找到了一个解决方案,如果错误来自于使用

subprocess
创建的新 python 进程。该版本利用
pty.openpty()
创建一个新的伪终端对。

import subprocess, pty, sys

# Create new tty to handle ioctl errors in termios
master_fd, slave_fd = pty.openpty()

proc = subprocess.Popen([sys.executable, 'my_program.py'], stdin=slave_fd)

希望这对其他人有帮助。


0
投票

我有这个问题:[teleop_twist_keyboard-4]回溯(最近一次调用最后): [teleop_twist_keyboard-4] 文件“/opt/ros/humble/lib/teleop_twist_keyboard/teleop_twist_keyboard”,第 33 行,位于 [teleop_twist_keyboard-4] sys.exit(load_entry_point('teleop-twist-keyboard==2.4.0', 'console_scripts', 'teleop_twist_keyboard')()) [teleop_twist_keyboard-4] 文件“/opt/ros/humble/lib/python3.10/site-packages/teleop_twist_keyboard.py”,第 134 行,在 main 中 [teleop_twist_keyboard-4] 设置 = saveTerminalSettings() [teleop_twist_keyboard-4] 文件“/opt/ros/humble/lib/python3.10/site-packages/teleop_twist_keyboard.py”,第 120 行,在 saveTerminalSettings 中 [teleop_twist_keyboard-4] 返回 termios.tcgetattr(sys.stdin) [teleop_twist_keyboard-4] termios.error: (25, '不适合设备的 ioctl') [错误] [teleop_twist_keyboard-4]:进程已死亡 [pid 141272,退出代码 1,cmd '/opt/ros/humble/lib/teleop_twist_keyboard/teleop_twist_keyboard --ros-args -r __node:=teleop_twist_keyboard_node --params-file /tmp/launch_params_6njk3z2k'].

© www.soinside.com 2019 - 2024. All rights reserved.