1

Can someone explain why SSH duplicates stdin back to to the screen when PTY allocation is forced and how I can disable it?

~% ssh -V
OpenSSH_5.5p1 Debian-6+squeeze2, OpenSSL 0.9.8o 01 Jun 2010
~% echo "This should only show up once." | ssh server.tld -tt '/bin/cat'
This should only show up once.
This should only show up once.
Eric Pruitt
  • 413
  • 1
  • 4
  • 10

2 Answers2

1

This actually turned out to be a pretty simple fix that I feel silly for overlooking. When you use -tt with SSH, SSH creates a pty but leaves the echo functionality enabled. To keep the text from being echoed back, prefix the command with stty -echo like so: ssh -t server.tld "stty -echo && command"

Eric Pruitt
  • 413
  • 1
  • 4
  • 10
0

I'm going to take a long shot here and guess that this is the local echo of the pty that you allocated. STDIN is being treated as the input of your terminal which is then being echoed back to you.

Off the top of my head I can't think of a sane way to deal with this, and I'm honestly inclined to say that it's not a good idea to try to do this anyway.

If you reply with a comment on why you feel that you must implement something this way, I will try to help you find an alternative solution out of band. I do not think that it will change this answer, however.

Andrew B
  • 32,588
  • 12
  • 93
  • 131
  • In what I have seen, I figured there probably is not an elegant solution to this problem. Right now, I am resorting to creating a pty, spawning ssh with the pty configured for stdin and forwarding all stdin from the parent process to the ssh client. I am trying to wrap the ssh client so that when the ssh client is used in a pipe, on the remote server, the called process sees the same values for isatty on std(in|out|err) that it would see if it were in a pipe series locally. – Eric Pruitt Jan 10 '13 at 02:57
  • Cool, that's a start. Are you able to tell me what you're trying to solve by faking the terminal? It'd help to make sure that this is in fact the best route to go. – Andrew B Jan 10 '13 at 03:04
  • I thought that was covered by my response. Locally, various program may change behaviour depending on whether or not you do `A | program`, `program | B`, `A | program | B` or `A | program | B 2> error.log`, etc. I need to be able to wrap any program so that the command so that it behaves the same way way in middle of a pipe even if it's across SSH. – Eric Pruitt Jan 10 '13 at 04:25
  • I was reaching for specific examples I guess. It's generally not something that I've had to do in my professional career. This isn't to say that there aren't legitimate reasons why you would need to do so, but I wanted to make sure that this wasn't going in the direction of "a hack for a hack for a hack". – Andrew B Jan 10 '13 at 04:34
  • Off the top of my head, `ls`'s colorization looks at whether or not stdout is a TTY, and `dialog` uses stderr by default to draw dialogue boxes and controls. Honestly, I cannot think of any other programs whether this is the case, but the whole point of the wrapper is to be able to integrate any remote SSH command into a local pipe such that the behaviour is virtually identical, and making the isatty returns identical is important to ensure this. Contrived example: `echo "X" | ls --color` shows color, but `echo "X" | ssh server.tld ls --color` does not, and forcing the tty makes dupe text. – Eric Pruitt Jan 10 '13 at 04:50
  • Yeah, there is no alternative solution for that. They're designed to operate that way because the output is only designed for consumption by a real terminal. Breaking that barrier introduces problems like `ssh -tt server.tld "ls --color" > ansijunk.txt` and `ssh -tt server.tld "ls --color" | less`, which is generally why the line is not crossed. You really need the knob for this sort of behavior to be in the client side but I suspect the only workarounds you're going to find are on the serverside. – Andrew B Jan 10 '13 at 05:16
  • Working around the isatty values is pretty easy. Essentially, if at any of stdout, stderr or stdin returns true for isatty() for the wrapper, I just tack on a "/bin/cat |" to the front (stdin) or " | /bin/cat" to the back for stdout and stderr with some exec magic for the latter. Although kludgey, it works for all `sh` compatible shells. The only problem at this stage is that SSH PTY allocation insists on echoing text back to the screen when I force it with `-tt` which is what I need a solution for. – Eric Pruitt Jan 10 '13 at 05:19