📜 ⬆️ ⬇️

Console of the 21st century: mosh, tmux, fish

In my work, I have to spend almost all my time in the console, both local and remote. No, that you, I'm not complaining, even on the contrary - I like the automation capabilities provided by console tools, and the work in the console is quite productive.

But if you spend with your tool up to 80% of the working time, it is advisable to make sure that you do not waste time and that the work gives you pleasure. In this article I would like to talk a little about the tools that I personally use every day, and how they improve the user experience (and, often, productivity) when working with the console and with remote servers in particular.

Ssh problems


When working with remote servers via ssh, there are many things that can be frustrating, but there are two main problems, and the first one is fundamentally insoluble in ssh:
')
  1. With high round-trip latency (> 100 ms), user input appears with a noticeable delay, and when using the mobile Internet with an edge (latency 1000 ms), work becomes like torture
  2. With temporary problems (a few minutes) with the delivery of packages, the connection can break with write failed: broken pipe, and you will find out about it only when you try to enter or when using settings like keepaliveinterval


The first problem is insoluble because ssh by-design is simply a transport for bytes, and existing applications rely on this behavior. Since ssh does not attempt to interpret this stream of bytes, it cannot predictive input. For me personally, this problem is most relevant, since I have to work with servers in Europe and the USA, and in the second case, the delay is about 200 ms and is fundamentally unavoidable, at least until the invention of quantum communication or something like that. The second problem manifests itself in our conditions relatively rarely, but it is still unpleasant to reinstall all the connections in case of network failures (and to restart the fallen applications, if they were not running for some reason in the screen).



Solution - mosh (MObile SHell)


The solution to the above problems is quite radical - mosh ( mosh.mit.edu ) is a separate client-server system that works via UDP and sends screen diffs instead of the approach used by SSH, which transmits bytes "as is". The initial connection is via ssh, but ssh only starts the mosh-server and exits after that. Because of this, connecting to the server using mosh takes a little longer than just using SSH.

In order to work through mosh instead of ssh, you need to install the mosh-client on your computer and the mosh-server on the remote host. In general, it is not necessary to install it system-wide - the daemon runs from under the user, and you can specify the server's binary when connecting (example: mosh - server / home / yuriy / bin / mosh-server my-server-hostname).

Since mosh sends screen diffs by udp, it is very different in its properties from the usual ssh via tcp / ip:

Connection never breaks
There is no "connection". When restoring network connectivity, you again begin to see the current state of the console. You can also change the way you connect to the server, for example, change the wi-fi access point, and everything will continue to work. This is especially useful when using VPN over the mobile Internet, which is a sample of instability.

Forget about the ability to scroll the history of the mouse wheel
Local scrolling will not work, as mosh draws everything in an alternate screen, and only shows the difference from the previous state, without sending the rest. In order for the story to be saved at least somewhere, you need to use screen or tmux, which will be described later. With a certain file, you can still get the mouse wheel to work, but the sensations will still be "wrong."

High latency turns on the predictive echo.
If you, for example, use SSH via EDGE, then I really do not envy you :). In this case, mosh is able to “understand” in what context it is now working and, in most cases, is able to adequately display your input even before at least something comes from the server. In the illustration below, the “underlined” text is the text entered by the user, but the echo (in most cases just text entered by the user) has not yet been received from the server. Also, even in the case of not too high latency (for example, 50ms, already noticeable by sight), mosh tries to show user input instantly if it is “sure” that the entered text is simply being returned from the server at the moment. Thus, in the case of latency of about 50-100 ms, work in a remote console becomes almost indistinguishable from local one. Except for the opportunity to see the story, as mentioned above.



All these things are achieved due to the fact that the server also "renders" the output from the console and keeps the current screen state in its memory. In mosh's tracker, there are suggestions to be able to keep history as well, so that you can refuse the additional layer in the form of screen / tmux, but so far the authors have not done anything in this direction.

Let's now move on to what tmux is and why it is better than screen:

Screen problems


Unfortunately, I am not a big screen expert, so I could name only two problems - the lack of support for dividing the screen vertically (instead of the horizontal one by default) and the slow development in general due to a very old code base. The usability of the screen also left much to be desired. The vertical separation support was filed in the new version of screen 4.2, but by that time I personally had already stopped using it. In general, screen is still a de facto standard, just like ssh, and you cannot write it off.

What is tmux and its advantages over screen


If you have never heard of terminal multiplexers (Terminal MUltipleXor), then the previous paragraph is unlikely to be clear to you. Therefore, I will tell a little about what it is:

Imagine the situation that you want to run some kind of long ssh operation, and your connection is falling off. Or you do not want to wait for its completion, because this command is “while true; do run-daemon; done. " By default, interactive sessions send a SIGHUP signal to all processes from this session when disconnected, and the processes are terminated.

This problem can be solved in different ways, for example, using the nohup command, which redirects the output to files and ignores SIGHUP. But a more interesting solution is to use terminal multiplexers, such as screen or tmux. When you first start, it usually starts a new session in which you can work, and this session is not tied tightly to your ssh connection. You can disconnect, for example, by closing the tab with an ssh connection, or by pressing Ctrl + BD (that is, first press Ctrl + B and then release Ctrl and press D), and all applications running inside tmux will remain intact. You can then connect back to this session by typing "tmux attach" or screen with a bunch of checkboxes, for example "-rD".



In general, tmux looks more user-friendly and supports quite interesting things out of the box:

  1. The above screen splitting is vertical, for example using Ctrl + B: split-vertical. Unfortunately, the new version of screen with the support of such a split screen can still not be found everywhere.
  2. The ability to connect to an existing session several times - tmux attach will connect you to an existing session without “throwing out” other connected users
  3. Rewind history using the mouse wheel by setting the mouse-mode on option
  4. No need to run "script" when trying to connect to another user's screen via sudo


Most likely, all the above things can be done within the framework of the screen, just tmux was originally designed more simple for the user and has more features. If you suddenly use iterm2, then it has built-in support for integrating with tmux, which can also be an argument in its favor.

And finally, let's talk about fish - friendly interactive shell

Disadvantages bash


Honestly, it's hard to say what the bash is about. The biggest advantage of bash is that it is the most common shell and that it stands by default on most Linux distributions, mac os x and even cygwin. Also, bash is posix-compatible, which means that you can replace / bin / sh with / bin / bash in the system and “it won't break anything.” However, the interactive capabilities of the bash are far behind another common competitor in the face of zsh, there is not even the right prompt in the bash. Most features in both bash and zsh are disabled by default. To use all the features of these shells, you need to either spend a significant amount of time setting them up, or use ready-made solutions, for example oh-my-zsh.

21st century interactive shell - fish


It’s enough to see once how the fish (friendly interactive shell) works and you don’t want to use anything else :). In general, fish is an interactive shell, not POSIX-compatible. That is, scripts written for / bin / sh or / bin / bash cannot be executed with it. The shell syntax is slightly different from the usual, see the examples below.

Main features:



There are also just minor nice improvements:



An example of the right prompt using CMD_DURATION and git_prompt:

$ cat ~/.config/fish/functions/fish_right_prompt.fish function fish_right_prompt if test $status = 0 echo -n (set_color green) else echo -n (set_color red) end echo $CMD_DURATION (set_color normal)ms (set_color yellow) (__fish_git_prompt "%s") (set_color normal) end 


Pay attention to the syntax of if-expressions - it is more like python than shell. The expression in brackets means “insert the result of the command execution” - this is written to bash as $ (...), the first dollar symbol is not required in fish.

Here is what it looks like:



The right prompt shows the command execution time in milliseconds, in green if the command was successful, and in red if an error occurred. The current branch, if any, is shown in yellow.

Integration of mosh, tmux and fish, conclusions


When using tmux and fish together, there are 2 possible problems, both of which are a bit unpleasant, but easily solved:

The output from stderr “disappears” - github.com/fish-shell/fish-shell/issues/2115 - is solved by running “fish 2> & 1” instead of just “fish”
By default, tmux sets the $ TERM environment variable to screen, although it supports the 256-color mode, so you need to set the “export TERM = screen-256color” environment variable to get a regular fish instead of a fallback to 16-color mode

Also, when using the right prompt in fish, as well as when dividing windows vertically in tmux, the client for mosh can begin to shift the right border during quick entry, which leads to temporary artifacts when drawing. This is due to the fact that mosh does not understand that the position of the frames separating the panels in tmux, as well as the position of the right prompt in fish is fixed, and shifts them when entered to the right, along with the rest of the text.

Total: all of the above tools are quite new, and have not yet been sharpened to the same state as the usual ssh + screen + bash combination, but over time the situation improves, developers take into account feedback from users and improve integration with other "new" tools.

In general, a bunch of mosh + tmux + fish for me decided a lot of small (and not so) problems associated with working in a remote console, without creating a lot of new ones. A large number of small, but convenient and useful features of each of the described tools, it seems to me, it is worthwhile to try them yourself.

Source: https://habr.com/ru/post/267797/


All Articles