4

I'd like to write some scripts that would open multiple terminal panes in a single window, much like tmux or screen.

I personally am well versed in tmux, and have used it for years, but other developers on our team don't want to know anything about it or other screen multiplexers.

To this end, I'd like to write scripts that can section themselves off in multiple panes in a single window. Is this possible with straight up bash?

My goals are to

  • avoid requiring node or something that needs to be installed, (like blessed-contrib), to keep the process as simple as possible.
  • write it using something preinstalled on most distros, and posix compatible.
  • have a single terminal window that gets broken up into panes, where each pane could be a running process or command prompt.
  • when someone hits ctrl+c it exits all panes, and returns to a single terminal.
Brad Parks
  • 1,669
  • 1
    You could quite easily wrap tmux in simple shell functions that do the most basic stuff, like split horizontally/vertically, switch to another window, etc. If you write something from scratch, you get something quite heavy that you have to maintain, and that they will have to learn. Better to base it off tmux with the option for them to later more smoothly stop using your shell wrappers. – Kusalananda Oct 25 '19 at 12:22

1 Answers1

3

I think it is safe to say that this can't be done purely with bash alone. You will either need a higher programming language like perl/python, or to control an instance of tmux with a script.

Here's a quick review of the technology involved:

  • In order to run a program in the terminal environment that it expects, you need to create a pseudo-terminal (pty) to host it.
  • ptys are created and controlled using syscalls like ioctl, and have a rather low-level API.
  • To do something like tmux, you would need to read the controlling-side of each pty constantly and then splice together those pieces onto the main program's terminal, using special terminal escape codes
  • Terminal capabilities (i.e. the escape sequences supported by a terminal for cursor positioning and bold/color/underline etc) have hundreds of variations, so if you want any sort of compatibility you'll want to use a library like ncurses to help you set up sub-windows.

There are some tools that let bash call ioctl but I don't think it can handle all the calls needed for pty allocation, and it isn't a standard tool anyway.

You might be able to get around that by manually creating pty device nodes but you'd need to run as root and it would be a mess.

bash can find out various terminal escape sequences from the tput command, and you can in fact write bash scripts that render windows of text, but without ncurses this is hard to do correctly and cross-platform and will take a ton of your time.

In short, I don't think you can pull this off with plain bash and posix tools.

Perl is installed on almost all unixes, and perl can make ioctl calls, so yes it should be possible to write this in perl even without installing any extra modules. However, again I expect it would take too long without at least using some extra helper modules like IO::Pty and Curses. But even with all this, there's a lot of work to do.

I think your best bet is to try scripting tmux. I've not done it before, but that post gives the appearance of a few-days project instead of a few-weeks-and-tons-of-learning project.

If your main objection is having to install tmux, you might try downloading and compiling a static binary of tmux, then distribute that with your script. A static binary avoids dependence on any library in the system, and should work on any modern Linux kernel of the right architecture. You could even compile binaries for multiple architectures and then have the script detect which binary to use.

M Conrad
  • 973
  • 4
  • 13