Vterm fails to get tty when invoking tmux, but only when vterm is started in a remote location
Issue
If you start vterm from a remote org-mode document, then it spawns a remote shell at that location (which is fantastic!)
However, if you try to access a tmux session via vterm, then it fails with the error:
open terminal failed: can't use /dev/tty
You can get around this however by spawning vterm locally, and then ssh-ing into the machine, and then running tmux, which will work successfully
Steps to reproduce
- Within emacs, in a remote document spawn
vterm - Run
tmux new-session -t test - Witness error message
Steps to work around
- Within Emacs, in a local document spawn
vterm - SSH into the remote machine from this vterm buffer
- Run
tmux new-session -t test - Witness no error message
Is it to do with the SSH_CONNECTION being the same one that Tramp uses?
Maybe it's a bug of tmux, see https://unix.stackexchange.com/questions/404173/shell-command-tmux-throws-cant-use-dev-tty-error/512979
( exec </dev/tty; exec <&1; tmux )
works for me.
I have the same issue. The fix does work for vterm/tmux, but if I use other terminal emulators, I do not run into the /dev/tty error to begin with.
Don't know enough to comment if its a vterm or tmux bug, though.
I did some investigation and I think this is a tramp feature/bug. The issue happens here: tramp-sh.el
tramp has something called heredoc, which is used to support arguments that exceed command line length.
However, when it thinks it need heredoc it changes stdin (0) to /dev/tty here unconditionally, resulting in mismatched fd 0 vs fd 1 and 2.
I have only started learning Emacs like a few weeks ago, so I have no idea it doing this is a good or bad thing.
Thankfully there is a simple workaround. When it determines if it should enter heredoc mode, it checks is the program argument is surrounded by single quotes, so you can do something like this:
(setq vterm-tramp-shells '(("docker" "sh")
("ssh" "'zsh'")))
Now tmux works!
In fact, this probably should be the default along with sshx (and maybe all the *sh) once someone more experienced than me has checked this reasoning.
Thanks for the insights! Both @raymond-w-ko and @jixiuf solutions work.