Home

Awesome

<h1 align="center"> <img src="https://github.com/jcubic/jquery.terminal/blob/master/assets/ascii_art.svg?raw=true&ver=2.44.1" alt="ASCII Art that represent text jQuery Terminal - JavaScript Library for Web Based Terminal Emulators" /> </h1>

JavaScript Library for Web Based Terminal Emulators

npm bower Build and test Coverage Status NPM Downloads jsDelivr Downloads Paid Support LICENSE MIT

Summary

jQuery Terminal Emulator is a plugin for creating command line interpreters in your applications. It can automatically call JSON-RPC service when a user types commands or you can provide your own function in which you can parse user commands. It's ideal if you want to provide additional functionality for power users. It can also be used to debug your application.

You can use this JavaScript library to create a web based terminal on any website.

Because with this library you need to code all the commands yourself, you can call it fake terminal emulator. In contrast to library that will give you access to real terminal like online SSH. To have real online SSH I suggest to use xterm.js library.

Features:

Demo

You can test current version at this URL:

or if it doesn't use latest version (because of jsDelivr cache) you can force it with this URL:

And development version using:

You can use any version you want, everything what jsDelivr GH API accepts.

Installation

Include jQuery library, you can use cdn from https://jquery.com/download/

or use jsDelivr:

<script src="https://cdn.jsdelivr.net/npm/jquery"></script>

Then include js/jquery.terminal-2.44.1.min.js and css/jquery.terminal-2.44.1.min.css

You can grab the files from CDN:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/2.44.1/js/jquery.terminal.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/2.44.1/css/jquery.terminal.min.css" rel="stylesheet"/>

or

<script src="https://cdn.jsdelivr.net/npm/jquery.terminal@2.44.1/js/jquery.terminal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery.terminal@2.44.1/css/jquery.terminal.min.css"/>

If you always want latest version, you can get it from unpkg without specifying version, it will redirect to the latest ones:

<script src="https://unpkg.com/jquery.terminal/js/jquery.terminal.min.js"></script>
<link href="https://unpkg.com/jquery.terminal/css/jquery.terminal.min.css" rel="stylesheet"/>

or jsDelivr that is bit faster:

<script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/jquery.terminal.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/jquery.terminal/css/jquery.terminal.min.css" rel="stylesheet"/>

Bleeding Edge Version

If you want to test bleeding edge, development version of jQuery Terminal. You can use those files:

<script src="https://cdn.jsdelivr.net/gh/jcubic/jquery.terminal@devel/js/jquery.terminal.min.js"></script>
<link href="https://cdn.jsdelivr.net/gh/jcubic/jquery.terminal@devel/css/jquery.terminal.min.css" rel="stylesheet"/>

but it's not refreshed as fast as rawgit was, because it's CDN and need to be propagated to different servers.

Keyboard key polyfill

NOTE: From version 1.0.0 if you want to support old browsers then you'll need to use key event property polyfill. You can check the support for it on can I use.

<script src="https://unpkg.com/js-polyfills/keyboard.js"></script>

or

<script src="https://cdn.jsdelivr.net/npm/js-polyfills/keyboard.js"></script>

Command Line

You can also install jQuery Terminal using command line, from bower repository:

bower install jquery.terminal

or npm registry:

npm install jquery.terminal

Example of usage

This is code that uses low level function, that gives you full control of the commands, just pass anything that the user types into a function.

jQuery(function($, undefined) {
    $('#term_demo').terminal(function(command) {
        if (command !== '') {
            var result = window.eval(command);
            if (result != undefined) {
                this.echo(String(result));
            }
        }
    }, {
        greetings: 'Javascript Interpreter',
        name: 'js_demo',
        height: 200,
        width: 450,
        prompt: 'js> '
    });
});

Here is a higher level call, using an object as an interpreter, By default the terminal will parse commands that a user types and replace number like strings with real numbers regex with regexes and process escape characters in double quoted strings.

$('body').terminal({
    cat: function(width = 200, height = 300) {
        return $(`<img src="https://placekitten.com/${width}/${height}">`);
    },
    title: function() {
        return fetch('https://terminal.jcubic.pl')
            .then(r => r.text())
            .then(html => html.match(/<title>([^>]+)<\/title>/)[1]);
    }
}, {
    checkArity: false,
    greetings: 'My Terminal\n'
});

And more advanced example:

jQuery(function($, undefined) {
    $('#term_demo').terminal({
        add: function(a, b) {
            this.echo(a + b);
        },
        re: function(re, str) {
           if (re instanceof RegExp && re.test(str)) {
              this.echo(str + ' [[;green;]match]');
           }
        },
        foo: 'foo.php',
        bar: {
            sub: function(a, b) {
                this.echo(a - b);
            }
        }
    }, {
        height: 200,
        width: 450,
        prompt: 'demo> '
    });
});

command add 2 2 will display 4 (not 22).

Command foo will change prompt to foo> and each new command will execute json-rpc method from foo.php script.

command bar will change the prompt to bar> and if you type sub 10 2 it will display 8. To exit from bar nested command you can type exit or press CTRL+D.

command re /^foo/ foo-bar will echo: "foo-bar match" where "match" will be green.

By default arguments are required but you can disable the check like this:

jQuery(function($, undefined) {
    $('#term_demo').terminal({
        add: function(...args) {
            this.echo(args.reduce((a,b) => a + b));
        }
    }, {
       checkArity: false
    });
});

And add command will accept any number of argments and it will sum them up (if they are numbers).

You can create JSON-RPC interpreter with authentication in just one line:

$('#term_demo').terminal('service.php', {login: true});

The rest of the code can be on the server, so you can write fully working application, without any front-end, that can be tested in browser.

First argument to terminal can also be array with objects strings and functions, with one requirement, that only one function can be used as last fallback for commands that was not found in RPC or in objects.

jQuery(function($, undefined) {
    $('#term_demo').terminal([{
        add: function(...args) {
            this.echo(args.reduce((a,b) => a + b));
        }
    } 'foo.php', function(command) {
       this.echo("You've typed " + command, {formatters: false, exec: false});
    }], {
       checkArity: false
    });
});

More examples here. You can also check Full Documentation or Getting Started Guide on Wiki.

Quick Start Tutorials

If you want to start with jQuery Terminal you can look at those tutorials:

The first tutorial is have all the basics, even if you're new to programming and JavaScript. The second one explain everything but it assume that you know the basics. If you pick the second and and stuck you can reference the first one. It's worth checking the first one anyway.

Security

Because of security in version 1.20.0 links with protocols different than ftp or http(s) (it was possible to enter javascript protocol, that could lead to XSS if author of the app echo user input and save it in DB) was turn off by default. To enable it, you need to use anyLinks: true option.

In version 1.21.0 executing terminal methods using extendend commands [[ terminal::clear() ]] was also disabled by default because attacker (depending on your application) could execute terminal::echo with raw option to enter any html and execute any javascript. To enable this feature from this version you need to use invokeMethods: true option.

The features are safe to enable, if you don't save user input in DB and don't echo it back to different users (like with chat application). It's also safe if you escape formatting before you echo stuff.

If you don't save user input in DB but allow to echo back what user types and have enabled execHash options, you may have reflected XSS vulnerability if you enable this features. If you escape formatting this options are also safe.

NOTE: To disable exec if you have execHash (or echo stuff from users with invokeMethods: true), you can also set option {exec: false} to your echo call and use it only when you get values from server (not from DB indireclty from users). If you do this you will be able to echo stuff from users and execute terminal methods from server (this feature is mostly done just for that).

Contributors

If you want to contribute read CONTRIBUTING.md first. Here are project contributors:

<!-- CONTRIBUTORS-START -->
<img src="https://avatars.githubusercontent.com/u/280241?v=4" width="100px;"/><br /><sub>Jakub T. Jankiewicz</sub><br>commits<img src="https://avatars.githubusercontent.com/u/49900772?v=4" width="100px;"/><br /><sub>Riccardo Mura</sub><br>commits<img src="https://avatars.githubusercontent.com/u/19851053?v=4" width="100px;"/><br /><sub>Jean-Michel Carrel</sub><br>commits<img src="https://avatars.githubusercontent.com/u/1208327?v=4" width="100px;"/><br /><sub>kid1412z</sub><br>commits<img src="https://avatars.githubusercontent.com/u/4943440?v=4" width="100px;"/><br /><sub>Marcel Link</sub><br>commits<img src="https://avatars.githubusercontent.com/u/6674275?v=4" width="100px;"/><br /><sub>Sébastien Warin</sub><br>commits<img src="https://avatars.githubusercontent.com/u/8646106?v=4" width="100px;"/><br /><sub>Christopher John Ryan</sub><br>commits
<img src="https://avatars.githubusercontent.com/u/715580?v=4" width="100px;"/><br /><sub>Johan</sub><br>commits<img src="https://avatars.githubusercontent.com/u/19733683?v=4" width="100px;"/><br /><sub>Snyk bot</sub><br>commits<img src="https://avatars.githubusercontent.com/u/273194?v=4" width="100px;"/><br /><sub>Florian Schäfer</sub><br>commits<img src="https://avatars.githubusercontent.com/u/375027?v=4" width="100px;"/><br /><sub>Tomasz Ducin</sub><br>commits<img src="https://avatars.githubusercontent.com/u/26783539?v=4" width="100px;"/><br /><sub>Qijia Liu</sub><br>commits<img src="https://avatars.githubusercontent.com/u/1751242?v=4" width="100px;"/><br /><sub>Ishan Ratnapala</sub><br>commits<img src="https://avatars.githubusercontent.com/u/4673812?v=4" width="100px;"/><br /><sub>David Refoua</sub><br>commits
<img src="https://avatars.githubusercontent.com/u/6078211?v=4" width="100px;"/><br /><sub>Antoine</sub><br>commits<img src="https://avatars.githubusercontent.com/u/588573?v=4" width="100px;"/><br /><sub>youurayy</sub><br>commits<img src="https://avatars.githubusercontent.com/u/5696096?v=4" width="100px;"/><br /><sub>Steve Kirkegard</sub><br>commits<img src="https://avatars.githubusercontent.com/u/179534?v=4" width="100px;"/><br /><sub>stereobooster</sub><br>commits<img src="https://avatars.githubusercontent.com/u/282724?v=4" width="100px;"/><br /><sub>Dev Kumar Gupta</sub><br>commits<img src="https://avatars.githubusercontent.com/in/29110?v=4" width="100px;"/><br /><sub>dependabot[bot]</sub><br>commits<img src="https://avatars.githubusercontent.com/u/1573141?v=4" width="100px;"/><br /><sub>coderaiser</sub><br>commits
<img src="https://avatars.githubusercontent.com/u/1833930?v=4" width="100px;"/><br /><sub>Yutong Luo</sub><br>commits<img src="https://avatars.githubusercontent.com/u/139603?v=4" width="100px;"/><br /><sub>Steve Phillips</sub><br>commits<img src="https://avatars.githubusercontent.com/u/1263192?v=4" width="100px;"/><br /><sub>Robert W</sub><br>commits<img src="https://avatars.githubusercontent.com/u/7055377?v=4" width="100px;"/><br /><sub>exit1</sub><br>commits<img src="https://avatars.githubusercontent.com/u/27475?v=4" width="100px;"/><br /><sub>Mateusz Paprocki</sub><br>commits<img src="https://avatars.githubusercontent.com/u/74179?v=4" width="100px;"/><br /><sub>Martin v. Löwis</sub><br>commits<img src="https://avatars.githubusercontent.com/u/28552977?v=4" width="100px;"/><br /><sub>KiddoV</sub><br>commits
<img src="https://avatars.githubusercontent.com/u/3868754?v=4" width="100px;"/><br /><sub>Jon Steinich</sub><br>commits<img src="https://avatars.githubusercontent.com/u/749175?v=4" width="100px;"/><br /><sub>John Jarvis</sub><br>commits<img src="https://avatars.githubusercontent.com/u/15666417?v=4" width="100px;"/><br /><sub>Jarry Shaw</sub><br>commits<img src="https://avatars.githubusercontent.com/u/102739519?v=4" width="100px;"/><br /><sub>jpaye</sub><br>commits<img src="https://avatars.githubusercontent.com/u/137852?v=4" width="100px;"/><br /><sub>Hraban</sub><br>commits<img src="https://avatars.githubusercontent.com/u/9531780?v=4" width="100px;"/><br /><sub>Hasan</sub><br>commits<img src="https://avatars.githubusercontent.com/u/336727?v=4" width="100px;"/><br /><sub>finlob</sub><br>commits
<img src="https://avatars.githubusercontent.com/u/79814820?v=4" width="100px;"/><br /><sub>Ezinne Anne Emilia</sub><br>commits<img src="https://avatars.githubusercontent.com/u/569896?v=4" width="100px;"/><br /><sub>Anton Vasilev</sub><br>commits<img src="https://avatars.githubusercontent.com/u/406705?v=4" width="100px;"/><br /><sub>Abdelrahman Omran</sub><br>commits<img src="https://avatars.githubusercontent.com/u/32747235?v=4" width="100px;"/><br /><sub>7twin</sub><br>commits
<!-- CONTRIBUTORS-END -->

jQuery Terminal Website contributors:

<!-- CONTRIBUTORS-WWW-START -->
<img src="https://avatars.githubusercontent.com/u/280241?v=4" width="100px;"/><br /><sub>Jakub T. Jankiewicz</sub><br>commits<img src="https://avatars.githubusercontent.com/u/79814820?v=4" width="100px;"/><br /><sub>Ezinne Anne Emilia</sub><br>commits<img src="https://avatars.githubusercontent.com/u/1004261?v=4" width="100px;"/><br /><sub>Marc Laporte</sub><br>commits<img src="https://avatars.githubusercontent.com/u/31372?v=4" width="100px;"/><br /><sub>Rich Morin</sub><br>commits<img src="https://avatars.githubusercontent.com/u/14358086?v=4" width="100px;"/><br /><sub>4s3ti</sub><br>commits<img src="https://avatars.githubusercontent.com/u/26324569?v=4" width="100px;"/><br /><sub>DInesh51297</sub><br>commits<img src="https://avatars.githubusercontent.com/u/512317?v=4" width="100px;"/><br /><sub>Logan Rosen</sub><br>commits
<!-- CONTRIBUTORS-WWW-END -->

Acknowledge

Projects include with the source code:

Other code used inside the project or inspired by:

ASNSI Art used by this project

Personal thanks:

Also thanks to:

BrowserStack

for cross-device testing opportunity.

Paid Support

You can request paid support, you can find details at support.jcubic.pl.

Star History

Star History Chart

License

Licensed under MIT license

Copyright (c) 2011-2024 Jakub T. Jankiewicz