Meefik's Blog

Freedom and Open Source

WebSocket implementation for UNIX shell

04 Aug 2016 | bash is a cross-platform implementation of WebSocket server on bash. Only busybox is required to work, instead of bash, you can use ash. Can be used in embedded systems.

Bash wrapper via web browser

To demonstrate the work prepared a simple script (file /cgi-bin/terminal), allowing you to access the shell from the browser. To do this, first you need to run httpd (from busybox) in the directory with

To run an example of work through the JQuery Terminal Emulator library, which allows you to implement the execution of simple commands and display the result of execution, you need to perform:

cd jquery.terminal
WS_SHELL="sh" httpd -p 8080

To run an example of work through the xterm.js library, thanks to which you can get a full-fledged terminal in the browser, you need to perform:

cd xterm.js
telnetd -p 5023 -l /bin/bash -f /etc/issue
WS_SHELL="telnet 5023" httpd -p 8080

After that, it is enough to open the page in the browser http://localhost:8080/cgi-bin/terminal, where the terminal command line should be displayed. In order to correctly process the change in the size of the terminal depending on the size of the window (in xterm.js), you need to have the “\l” symbol in the issue file. Or simply type tty in the browser to display the current pty device.

Manual start

You can do it without httpd by running manually, but when you reload the browser page, the script will have to be run again:

WS_SHELL="cat" nc -l -p 5000 -e

This uses the NetCat version from busybox, which has the “-e” parameter. You may also need to specify a different path to the interpreter in the script itself, for example, as follows:

#!/bin/busybox ash

Now from the browser you can connect to the server on port 5000 via WebSocket:

var port = 5000;
var ws = new WebSocket('ws://' + location.hostname + ':' + port);
ws.onmessage = function(ev) {
  var textDecoder = new TextDecoder();
  var fileReader = new FileReader();
  fileReader.addEventListener('load', function () {
    var str = textDecoder.decode(fileReader.result);
    console.log('Received data: ', str);
ws.onopen = function() {

The layer was created for Linux Deploy to be able to manage containers from the browser, but it can also be used for other purposes.