While building a small expect script I noticed that, after executing the script, some characters were automatically on the input of bash. I have seen that on other programs before, but here I have something reproducable.

So as you can see on the fifth line of the output, there are some random characters on stdout (^[[51;117R) and some of them leak onto the shell input line (;117R). If I press enter after executing the expect script, bash then tries to interpret that (;117R) as if I had entered it into bash.

I hope you have checked these characters are nothing to do with your password before posting?
– Philip CoulingFeb 6 at 16:19

Yes. The password is being passed as the second parameter as in the first line of the second code block. It is just the characters that are visible. The only non-visible input that is added after the command expect test.exp 192.168.0.2 root is one press of the Enter key.
– DakkaronFeb 6 at 16:21

The ^[[51;117R sequence is described on wikipedia as "xterm replies CSI row ; column R if asked for cursor position and CSI 1 ; modifiers R if the F3 key is pressed with modifiers, which collide in the case of row == 1. This can be avoided by using the ? private modifier, which will be reflected in the response." -- but that doesn't address your question. I'd look at the definition of root's prompt on the remote machine, but that still doesn't address the question.
– glenn jackmanFeb 6 at 19:06

1 Answer
1

Something run during the log-on process for the remote system is, by sending a Device Status Report control sequence to its terminal, requesting a Cursor Position Report from that terminal. The terminal (your terminal, several hops away, passed the DSR output via ssh and expect) is duly generating and sending it.

% printf '\x1b[6n' ; console-decode-ecma48
^[[30;1R
CPR 30;1
LF
%

Such reports arrive from a terminal to the host (i.e. the machine directly connected to the terminal) in exactly the same way as typed input does. Programs running on the host have no reliable way to know that you did not simply type that Cursor Position Report. Of course expect is not reading and sending on terminal input at that point, so the CPR has queued up to be read by the next program that does read input from your terminal, which is your shell after expect has finished. What you are seeing is how your shell reacts to such control sequences as input.

Such things are one of the reasons that terminal input processing should really always be a proper ECMA-48 decoder with a proper state machine. Your shell's line editing system is not. (None of ZLE, Readline, or libedit really handle terminal input control sequences properly.) It is decoding things using pattern matching, which does not do the right thing. Notice how it has only ignored the first four characters of the control sequence. A proper ECMA-48 input decoder would decode the whole control sequence, including all of the Parameter characters up to the Final character, recognize it as a CPR, and (one hopes) throw it away as input for which it has no use.

As to what is requesting the CPR in the first place: For that you'll have to inspect the remote system, and what programs it runs at terminal log-on. A likely culprit is the Xterm resize program. (Note that you should not use that program when Xterm is not your terminal, as it will incorrectly set the TERM environment variable to an xterm type.) But resize is not the sole possibility.