ini
This commit is contained in:
96
pty_monitor.py
Normal file
96
pty_monitor.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import sys
|
||||
import os
|
||||
import pty
|
||||
import tty
|
||||
import termios
|
||||
import select
|
||||
import re
|
||||
import getpass
|
||||
import datetime
|
||||
import itertools
|
||||
|
||||
|
||||
def get_log_filename():
|
||||
"""Ermittelt einen Dateinamen basierend auf Username und TTY-Nummer."""
|
||||
try:
|
||||
username = getpass.getuser()
|
||||
except Exception:
|
||||
username = "user"
|
||||
|
||||
try:
|
||||
tty_path = os.ttyname(sys.stdout.fileno())
|
||||
tty_number = os.path.basename(tty_path)
|
||||
filename = f"{username}-tty{tty_number}.log"
|
||||
except OSError:
|
||||
for i in itertools.count():
|
||||
filename = f"{username}-tty{i}.log"
|
||||
if not os.path.exists(filename):
|
||||
break
|
||||
return filename
|
||||
|
||||
|
||||
def sanitize_output(data: bytes) -> bytes:
|
||||
"""Entfernt Steuerzeichen und -sequenzen, um die Log-Datei lesbarer zu machen."""
|
||||
data = re.sub(
|
||||
rb'\x1b(\[[0-?]*[ -/]*[@-~]|\][^]*(\x07|\x1b\\))', b'', data)
|
||||
data = data.replace(b'\r', b'')
|
||||
data = data.replace(b'\b', b'')
|
||||
data = data.replace(b'\a', b'')
|
||||
return data
|
||||
|
||||
|
||||
def run_interactive_shell():
|
||||
log_filename = get_log_filename()
|
||||
print(f"Sitzung wird in '{log_filename}' aufgezeichnet.")
|
||||
|
||||
file_existed = os.path.exists(log_filename)
|
||||
original_termios = termios.tcgetattr(sys.stdin.fileno())
|
||||
|
||||
try:
|
||||
# Öffne die Datei im 'append binary'-Modus ('ab')
|
||||
with open(log_filename, 'ab') as log_file:
|
||||
if file_existed:
|
||||
# Füge einen Trenner für die neue Sitzung hinzu
|
||||
timestamp = datetime.datetime.now().isoformat()
|
||||
separator = f"\n\n--- NEUE SITZUNG GESTARTET AM {
|
||||
timestamp} ---\n\n".encode('utf-8')
|
||||
log_file.write(separator)
|
||||
|
||||
pid, master_fd = pty.fork()
|
||||
|
||||
if pid == 0:
|
||||
os.execv("/bin/zsh", ["/bin/zsh"])
|
||||
else:
|
||||
tty.setraw(sys.stdin.fileno())
|
||||
|
||||
while True:
|
||||
try:
|
||||
readable, _, _ = select.select(
|
||||
[sys.stdin, master_fd], [], [])
|
||||
|
||||
if sys.stdin in readable:
|
||||
user_input = os.read(sys.stdin.fileno(), 1024)
|
||||
if not user_input:
|
||||
break
|
||||
log_file.write(sanitize_output(user_input))
|
||||
os.write(master_fd, user_input)
|
||||
|
||||
if master_fd in readable:
|
||||
shell_output = os.read(master_fd, 1024)
|
||||
if not shell_output:
|
||||
break
|
||||
log_file.write(sanitize_output(shell_output))
|
||||
os.write(sys.stdout.fileno(), shell_output)
|
||||
sys.stdout.flush()
|
||||
|
||||
except OSError:
|
||||
break
|
||||
finally:
|
||||
termios.tcsetattr(sys.stdin.fileno(),
|
||||
termios.TCSADRAIN, original_termios)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Starte PTY-Monitor. Gib 'exit' ein, um die Sitzung zu beenden.")
|
||||
run_interactive_shell()
|
||||
print(f"\nPTY-Monitor beendet.")
|
||||
Reference in New Issue
Block a user