To use a command-line program with an interactive TTY, you just need to execute that program in a shell (of course, the program needs to do blocking I/O operations on STDIN/STDOUT). For example : python -i.
But you can also do this: cat - | python -i. This is useful to feed STDIN with a file first then with an interactive TTY. For example: cat prelude.py - | python -i. This way you get an interactive TTY after piping the whole content of the script into STDIN. I know there are other ways to load a script in the Python interactive shell, this is just an example.
I want to write a Python script that behave the same way. Here is my current testing script:
import os
import sys
import threading
def main():
thread_loop = True
def thread_func():
unbuf_fd = os.fdopen(sys.stdin.fileno(), 'rb', 0)
sys.stdin.close()
sys.stdin = unbuf_fd
unbuf_fd = os.fdopen(sys.stdout.fileno(), 'wb', 0)
sys.stdout.close()
sys.stdout = unbuf_fd
while(thread_loop):
sys.stdout.write(sys.stdin.read(1))
sys.stdout.write(b'Exiting...\n')
def signal_func(sig, frame):
global thread_loop
print('You pressed Ctrl+C.')
thread_loop = False
forward_std = threading.Thread(target=thread_func, args=())
forward_std.start()
forward_std.join()
if __name__ == '__main__':
main()
Both python test.py and cat - | python test.py work but unlike python -i i have an echo of what's poured into STDIN.
How can I disable this echo ? The following code works with python test.py:
fd = sys.stdin.fileno()
fd_attr = tty.tcgetattr(fd)
tty.setcbreak(fd)
But with cat - | python test.py I get the following error:
Traceback (most recent call last):
File "tata.py", line 33, in <module>
main()
File "tata.py", line 25, in main
fd_attr = tty.tcgetattr(fd)
termios.error: (25, 'Inappropriate ioctl for device')
Is there a generic way to disable echo for STDIN wether it's piped or not ? Is there a specific way to disable echo for a piped STDIN and that I can use when sys.stdin.isatty() return False?
Thanks for your advice !