1

I have a piece of python code that injects entries from the bash history into the command prompt.

Everything worked perfectly until I switched to Python 3. Now German Umlaute appear wrong.

eg.

python3 console_test.py mööp

results in:

$ m�

Here's the relevant code:

import fcntl
import sys
import termios

command = sys.argv[1]

fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
new = termios.tcgetattr(fd)
new[3] = new[3] & ~termios.ECHO  # disable echo
termios.tcsetattr(fd, termios.TCSANOW, new)
for c in command:
    fcntl.ioctl(fd, termios.TIOCSTI, c)
termios.tcsetattr(fd, termios.TCSANOW, old)

I tried encoding the input to utf-8 but that gave me:

OSError: [Errno 14] Bad address
Vindolin
  • 827
  • 8
  • 12

1 Answers1

1

Found the answer myself, Python3 automatically decodes the arguments with the filesystem encoding so I had to reverse that before calling the ioctl:

import fcntl
import sys
import termios
import struct
import os

command = sys.argv[1]

if sys.version_info >= (3,):
    # reverse the automatic encoding and pack into a list of bytes
    command = (struct.pack('B', c) for c in os.fsencode(command))

fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
new = termios.tcgetattr(fd)
new[3] = new[3] & ~termios.ECHO  # disable echo
termios.tcsetattr(fd, termios.TCSANOW, new)
for c in command:
    fcntl.ioctl(fd, termios.TIOCSTI, c)

termios.tcsetattr(fd, termios.TCSANOW, old)
Vindolin
  • 827
  • 8
  • 12