1

I have written an SSH wrapper script that does local line editing. It is invoked similarly to SSH. For example: python3 sshwrapper.py user@example.com -CX. The problem is that when I connect to a remote computer using this script and use vim or tmux there, some garbage is printed. This problem is not specific to SSH, since the problems also appear when I use this script to wrap bash instead of ssh.

Examples:

  • After starting tmux, some garbage is printed after the bash prompt:

    abc@me:~$ ^[[?65;1;9c

  • When opening a new file in Vim using vim mynewfile.txt, this appears on the first line:

    ^[[2;2R^[[>65;6003;1c^[]10;rgb:0000/0000/0000^G^[]11;rgb:ffff/ffff/dddd^G

How do I fix the problem?

This is the script in question:

import os
import pty
import select
import signal
import subprocess
import sys

master_fd, slave_fd = pty.openpty()
process = subprocess.Popen(['ssh'] + sys.argv[1:],
                           stdin=slave_fd,
                           stdout=slave_fd,
                           stderr=subprocess.STDOUT,
                           # Important for Ctrl-c in the remote terminal.
                           preexec_fn=os.setsid)

def sigint_handler(_signum, _frame):
    os.write(master_fd, b'\03')  # Send Ctrl-c.
signal.signal(signal.SIGINT, sigint_handler)

def sigtstp_handler(_signum, _frame):
    os.write(master_fd, b'\x1A')  # Send Ctrl-z.
signal.signal(signal.SIGTSTP, sigtstp_handler)

def sigchld_handler(_signum, _frame):
    process.wait()
    sys.exit(process.returncode)
signal.signal(signal.SIGCHLD, sigchld_handler)

while process.poll() is None:
    # Block until there is something to read or write.
    r, w, e = select.select([sys.stdin, master_fd], [], [])
    if sys.stdin in r:
        # Write to SSH.
        user_input = os.read(sys.stdin.fileno(), 4096)
        if not user_input:
            os.write(master_fd, b'\04')  # Send Ctrl-d.
        else:
            os.write(master_fd, user_input)
    if master_fd in r:
        # Read from SSH.
        data = os.read(master_fd, 4096)
        sys.stdout.write(data.decode())
        sys.stdout.flush()

I am using Python 3.8.10 on Ubuntu 20.04 on both my local computer and the remote computer. This is a self-education project, so I am writing the program using Python standard libraries only.

Flux
  • 9,805
  • 5
  • 46
  • 92

3 Answers3

0

There is a bad hack you can try. After ssh into the machine try removing env variable LS_COLORS

export LS_COLORS=none

This change will persist in your session.

gettinggud
  • 13
  • 4
  • `export LS_COLORS=none` has no effect on the situation. – Flux Nov 26 '21 at 07:29
  • Have you tried https://pypi.org/project/termcolor/ – gettinggud Nov 26 '21 at 07:41
  • This is a self-education project, so I am writing the program using Python standard libraries only. – Flux Nov 26 '21 at 07:45
  • In this case all I can suggest is to add some filters to display/remove colors: [link](https://opensource.com/article/19/9/linux-terminal-colors) [link](https://chrisyeh96.github.io/2020/03/28/terminal-colors.html#ansi-escape-codes-for-terminal-graphics). Nice project btw! – gettinggud Nov 26 '21 at 07:57
  • What is the underlying cause of the problem? – Flux Nov 26 '21 at 08:03
0

In your bashrc:

alias tmux="TERM=screen-256color-bce tmux"

In your .tmux.conf:

set -g default-terminal "xterm-256color"

pygeek
  • 7,356
  • 1
  • 20
  • 41
0

Try to run your script from a different terminal application (preferably set to the defaults) and see if you still have the problem.