قراءة حرف واحد (نمط getch) في بيثون لا يعمل في يونكس

StackOverflow https://stackoverflow.com/questions/1052107

  •  20-08-2019
  •  | 
  •  

سؤال

وأي وقت يمكنني استخدام وصفة في http://code.activestate.com/recipes/134892 / أنا لا يمكن أن يبدو للحصول على عمل. كان دائما يلقي الخطأ التالي:

Traceback (most recent call last):
    ...
    old_settings = termios.tcgetattr(fd)
termios.error: (22, 'Invalid argument)

وأفضل فكرتي هي أن يكون ذلك بسبب أنا على التوالي في الكسوف حتى termios هو رمي نوبة حول واصف الملف.

هل كانت مفيدة؟

المحلول

وهذا يعمل على أوبونتو 8.04.1، بايثون 2.5.2، أحصل على أي خطأ من هذا القبيل. قد يكون عليك أن تحاول ذلك من سطر الأوامر، كسوف قد تستخدم ستدين الخاصة به، وأحصل على نفس بالضبط الخطأ إذا كنت تشغيله من الجناح IDE، ولكن من سطر الأوامر يعمل كبيرة. السبب هو أن IDE منها مثلا الجناح تستخدم هناك netserver.CDbgInputStream الدرجة الخاصة كما sys.stdin حتى sys.stdin.fileno هو صفر، ولهذا السبب الخطأ. في الأساس IDE ستدين ليس الكتابة البعيدة (sys.stdin.isatty الطباعة () غير صحيح)

class _GetchUnix:
    def __init__(self):
        import tty, sys

    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch


getch = _GetchUnix()

print getch()

نصائح أخرى

ووضع محطة في وضع الخام ليست دائما فكرة جيدة. في الواقع يكفي لمسح ICANON قليلا. هنا هو نسخة أخرى من getch () مع دعم المهلة:

import tty, sys, termios
import select

def setup_term(fd, when=termios.TCSAFLUSH):
    mode = termios.tcgetattr(fd)
    mode[tty.LFLAG] = mode[tty.LFLAG] & ~(termios.ECHO | termios.ICANON)
    termios.tcsetattr(fd, when, mode)

def getch(timeout=None):
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        setup_term(fd)
        try:
            rw, wl, xl = select.select([fd], [], [], timeout)
        except select.error:
            return
        if rw:
            return sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

if __name__ == "__main__":
    print getch()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top