Mosh: add $MOSH_VERSION or other helper variables for session children

Created on 30 Mar 2016  Â·  11Comments  Â·  Source: mobile-shell/mosh

mosh-server could usefully set a MOSH_VERSION variable, and/or others, to help login session processes to identify that they're running under Mosh and possibly further session-specific info.

The idea came up for #178, where it would be useful to support a hackish workaround-- but it's more generally useful than that. On OS X, Terminal.app and iTerm2 set TERM_PROGRAM, for example.

Most helpful comment

MOSH_VERSION actually sounds _less_ reliable as a solution to #178 or anything similar, since it would be inherited inside screen and tmux.

I would suggest MOSH_TTY, analogous to SSH_TTY. It would still be inherited, but at least that can be detected by matching its value against the current terminal:

if [ "$(tty)" = "$MOSH_TTY" ]; then
    …
fi

All 11 comments

MOSH_VERSION actually sounds _less_ reliable as a solution to #178 or anything similar, since it would be inherited inside screen and tmux.

I would suggest MOSH_TTY, analogous to SSH_TTY. It would still be inherited, but at least that can be detected by matching its value against the current terminal:

if [ "$(tty)" = "$MOSH_TTY" ]; then
    …
fi

Actually MOSH_TTY doesn’t even solve the problem. If you use mosh to start a screen, close mosh, reattach the screen elsewhere, and create a new screen window, then it could have its environment inherited _and_ its TTY reused from the closed mosh-server.

The only reliable solution I can think of is to additionally leave open a pipe or socket back to mosh-server, referenced by MOSH_FD, that a child can query to detect whether the mosh-server has been closed…

(Really, UNIX? Really?)

Or or maybe mosh-server exports its PID as MOSH_PID and edits its own argv to add the TTY name?

Just posting this snippet as a workaround I have in my .profile to detect if I'm connected via mosh.

ps -p $PPID | grep mosh-server > /dev/null
if [[ "$?" == "0" ]]; then
  export MOSH=1
else
  export MOSH=0
fi

I don't think MOSH_PID by itself is reliable either since PIDs can be reused. The only way you can use that safely is if you follow the chain of parent PIDs and find $MOSH_PID in there.

We could implement something like an --check-mosh-session option in mosh.pl...

As far as nesting mosh/screen, what really ought to happen is that, whenever a given terminal emulator is started, it unsets all environment variables specific to a different terminal emulator, before setting its own.

I've collected a list:

COLORFGBG
COLORTERM
COLORTERM_BCE
ETERM_THEME_ROOT
ETERM_VERSION
GUAKE_TAB_UUID
KONSOLE_DBUS_SERVICE
KONSOLE_DBUS_SESSION
KONSOLE_DBUS_WINDOW
KONSOLE_PROFILE_NAME
MLTERM
MRXVT_TABTITLE
PROFILEHOME
QT_QPA_PLATFORM
SHELL_SESSION_ID
SSH_CLIENT
SSH_CONNECTION
SSH_TTY
STY
TERM
TERMINATOR_DBUS_NAME
TERMINATOR_DBUS_PATH
TERMINATOR_UUID
TERM_PROGRAM
TMUX
TMUX_PANE
VTE_CJK_WIDTH
VTE_VERSION
WINDOW
WINDOWID
XMODIFIERS
XTERM_LOCALE
XTERM_SHELL
XTERM_VERSION

Of course, adding DCS/SOS/OSC/PM/APC escape sequences is how you really should be communicating with your terminal if you want to be sure, but that does have the problem of being asynchronous, and besides we have to deal with legacy applications (ugh).

@cgull The parent PID chain fails if something in the middle has double-forked. Admittedly, I doubt anyone expects to be doing terminal magic after double-forking.

The idea with editing argv (maybe I meant comm) was that you could then check [ "$(ps -o comm= -q "$MOSH_PID")" = "mosh-server for $(tty)" ], in case you were feeling like your day wasn’t already complicated enough.

@o11c There’s no way you can expect every terminal to know about every other terminal in the world—how would anyone ever write a new one?

Do it via a directory in /etc/ (to which each terminal emulator adds a file when it is installed), similar to terminfo - or maybe even talk to the terminfo maintainer about it.

Remember, it has proven completely implausible to get people to stop lying about $TERM (and mosh is no exception), even though making new terminfo entries of the form "xterm-mosh" would probably do the right thing.

Of course, creating more terminal emulators is not a good thing, if they aren't well-behaved. We should probably create and standardize some DCS sequences for direct and chain identification (if there isn't an existing one I've overlooked - I'll admit my knowledge is far broader for CSI than for the other controls).

For mosh, the identification reply should look something like: <some-prefix> mosh : xterm : ansi | <identification of whoever started mosh><st>

@o11c The client application may not be running on the same filesystem where the terminal is installed, due to say SSH or containers. Hence why terminfo entries ship with ncurses, not with individual terminals. And even if we got a new terminal entry into ncurses, it would be a long time before it would be on enough systems to be useful (to say nothing of non-GNU curses implementations).

<identification of whoever started mosh> could have scary privacy implications; is there a need for that?

@o11c The client application may not be running on the same filesystem where the terminal is installed, due to say SSH or containers.

That case is already handled due to the fact that SSH drops all but a whitelist of environment variables. The main hard case is when the user starts one terminal emulator (including screen/tmux) from within another terminal emulator.

And even if we got a new terminal entry into ncurses, it would be a long time before it would be on enough systems to be useful (to say nothing of non-GNU curses implementations).

Thus why shipping our own files in XDG_CONFIG_DIRS. But even with the ncurses approach, there could be a hard-coded list to start at least.

<identification of whoever started mosh> could have scary privacy implications; is there a need for that?

Middleware like mosh will never be perfect. For example, no matter how hard you try, if the client is running under TERM=linux, you won't get more than 16 colors, you won't get more than 256 unique glyphs. Sufficiently intelligent applications will occasionally want information about non-innermost terminals.

Of course, it's always possible that some terminal won't actually support it - but we still need to plan and document it. But I'm not sure why it would be deliberately hidden, since it's limited to (approximately) the true value of TERM if it wasn't lying.

Update: there is an already-existing way to request the immediate TERM name (but no chaining), though xterm has this behind a runtime flag: Request Termcap/Terminfo String

$ printf '\eP+q544e;6e616d65\e\\'; cat
^[P1+r544e=787465726D;6e616d65=787465726D^[\

There is also one for version, already well-supported by many terminal emulators and without requiring a runtime flag:

$ printf '\e[>c'; cat
^[[>41;327;0c

See xterm's documentation for more information.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

skrat picture skrat  Â·  4Comments

andschwa picture andschwa  Â·  4Comments

cshei picture cshei  Â·  5Comments

a-b picture a-b  Â·  6Comments

pravi picture pravi  Â·  5Comments