I'm working on a research project and am trying to read what a user is entering into the terminal, stopping the execution while the command is evaluated, and then resuming (or closing) the session.
I found this example in the docs that opens a new session, records everything, and writes it to a file.
After cutting extras I ended up with this:
import os, pty
shell = os.environ.get('SHELL', 'sh')
with open('typescript', 'w') as script:
def read(fd):
data = os.read(fd, 1024)
# Parse on the hash
cmd = data.decode()
before, sep, after = cmd.rpartition("#")
script.write(after)
return data
pty.spawn(shell, read)
This has two problems, one is that it's reactive and the other is that it also captures any output from a given command.
When looking for another way I found this answer to a different question:
def wait_key():
''' Wait for a key press on the console and return it. '''
result = None
if os.name == 'nt':
import msvcrt
result = msvcrt.getch()
else:
import termios
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
try:
result = sys.stdin.read(1)
except IOError:
pass
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
return result
I read the terminos docs and think this may be the way to go but I don't understand how to adapt it to act on the ENTER key.
EDIT: What I'm doing is evaluating the commands with a machine learning model and deciding whether or not to allow the command to execute, like preventing someone from sudo rm -rf /. This is really just a proof-of-concept and demonstration.
Is there possibly a better way to go about this?