Swell.sh is a terminal for bash designed for use on mobile phone web browser, it comes with convenient features such as autocomplete suggestion and gesture typing keyboard. It is useful for quickly troubleshooting server problems on the go, or in your bed in the middle of the night. If you occassionally use the SSH app on your phone, you may want to give Swell.sh a try!
Diagram:
+-------------+ +--------------+ +--------------+
| | | | | |
| | WebSocket | | spawn | Bash process |
| Client Side +-------------> Server Side +---------->+ |
| <-------------+ | | |
| Browser | | Python | pty | |
| | | +-----------> |
| Chrome / | | API & WS <-----------+ |
| Safari | | | | |
| | | Static File | ptrace | |
| | | +-----------> |
| | | | | |
+-------------+ +--------------+ +--------------+
Swell.sh is a client-server application that 1) spawns a Bash process and 2) opens a HTTP server. It allows users to connect to the server on their mobile browser, then they could interact with the Bash process via the Web terminal UI, kind of similar to using a SSH client App on your phone.
The difference is that the Web-based UI is designed to use on mobile phone and has a virtual keyboard built-into the app that gives features like autocomplete suggestion and swipe gesture (by utilizing information provided by the server process). Think of something like your phone's keyboard trying to suggest the next word you may want to type, but instead of natural language, now it suggests Bash's Tab completion. Take a look at the GIF above to see what it means.
Table Of Content:
- Features
- Installation
- NOTE ON SECURITY
- Limitations
- NeoVim Autocomplete support
- Tmux support setting
- Termux support setting
- FAQ, User Manual, Tips
- Acknowledgement
- Licence
- Open-source & self-hosted
- Web-based client, works on Chrome on Android and Safari on iOS
- Autocomplete suggestion for commands and path names just like when you type Tab in Bash, works with Bash completion installed on the server (eg: git status, git log)
- Swipe gesture input
- support partial path so that you don't need to swipe the whole gesture for long commands, i.e., swiping 'user' would likely to suggest 'useradd', 'userdel', etc
- Works for bash inside Tmux (See
Tmux support setting
below) - Works on Termux on Android (See
Termux support setting
below) - NeoVim autocomplete (See
NeoVim Autocomplete support
below)
If you like the idea of this project and find it useful, please consider making a donation to support the continued development of Swell.sh via PayPal here
Commercial support/priority bug fixes/custom feature development are available, corporate sponsorship is very welcomed. Please contact via email (see Github Profile)
Requirements:
-
64-bit Linux
-
bash
- version tested: 4.2 - 4.4
- the
bash
that comes with most Linux distros (eg: Ubuntu 16.04/18.04, Debian stretch 9.7, CentOS 7.6, Fedora 29 are tested) should work with Swell.sh, unless you've overridden the system default one with your own compiled version
-
python 3.6+, virtualenv, pip
-
bash-completion
package - https://github.com/scop/bash-completion (optional, but highly recommended, maybe pre-installed on your system but if not, could be easily installed from most distro's package manager) -
ptrace_scope
setting as follow:In order for Swell.sh to work properly, you have to configure your system's
ptrace_scope
to appropriate value. First check:
cat /proc/sys/kernel/yama/ptrace_scope
- If the value is 3, won't work ¯\_(ツ)_/¯
- If the value is 0/1, you are good to go. (but if it's 1 and you want to work with Tmux you have to read the section on that below)
- If the value is 2, you can still make it to work by changing some setting (though it requires root once, but not for running Swell.sh) Please first check https://www.kernel.org/doc/Documentation/security/Yama.txt for the implication of the modification. Either:
- [Recommended] Add the capability
cap_sys_ptrace
to the python interpreter in your virtualenv, by:sudo setcap cap_sys_ptrace=eip <path to python interpreter like venv/bin/python>
(If you do not have setcap command, please google how to install on your system) - OR Change the value back to 0/1 by entering a root shell (
sudo su
) thenecho 0/1 > /proc/sys/kernel/yama/ptrace_scope
- [Recommended] Add the capability
git clone https://github.com/wcchoi/swell.sh
cd swell.sh
virtualenv -p python3 venv
source venv/bin/activate
pip install -r requirements.txt
cd swell.sh
source venv/bin/activate
python app.py # default options: --host=127.0.0.1 --port=8010
- Android Chrome/iOS Safari
- navigate to
<HOST>:<PORT>
, you may need to turn on VPN connection/SSH port forwarding on your phone (see the security notes below)
- navigate to
Do NOT expose the server publicly on the Internet without proper authentication and encryption, use it behind a VPN/SSH port forwarding. Otherwise anyone who can access the URL could control your system.
If you plan on exposing the server to Internet, please run it behind a reverse proxy (eg: Nginx, Apache, Caddy), and configure HTTPS and basic authentication (NOTE: unfortunately Basic Auth for WebSocket does not work for iOS Safari, please use other methods) to encrypt the data traffic and limit access. You will need to set the listening interface (--host
flag) to 0.0.0.0
as well when running app.py
Also, please note that Swell.sh itself is not using SSH protocol (it uses WebSocket to interact with a Bash process on the server via pty), and I am no security expert, so it's possible there are places in the code that do not follow the best/strictest security practice. If you have concern/doubt over that, please audit the code and all the third party dependencies and then decide yourself.
If you find vulnerabilities/places where security could be improved, please contact me via email for discussion. Thanks for the help!
These are the current limitations, some maybe fixed in future update. PR welcome!
- Server works on 64-bit Linux only
- Bash shell only (your login shell config on the system is ignored)
- also the autocomplete suggestion works on the outermost bash (the one spawned by app.py) only, if you enter a new bash sub-shell, or SSH to other server, it won't work
- Client is only tested to work on the latest version of Chrome on Android and Safari on iOS (that I have access to), older/other browser may still work (some polyfills are applied), but YMMV
- Single-session only, i.e.: if multiple client devices are simultaneously connected, they will be looking at the same thing
- Keyboard is US QWERTY layout only
- Keyboard is single-touch only, so you CANNOT press-hold the CTRL key then tap C key to input CTRL-C, have to tap CTRL and then tap C
- Keyboard does not support some key yet, eg: F1/F2, Page-up/down, CTRL-]/CTRL-^, CTRL-ALT+X, etc
- The bug of autocomplete suggestion that sometimes it gives no/wrong suggestion (though you can still input a TAB key to trigger autocomplete just like on normal keyboard)
- Accuracy of the swipe gesture input may not be high
- NOTE: currently the swipe gesture algorithm works best when the full/longer path is traced
- The PATH env var is not refreshed, i.e. the autocomplete suggestion would not detect change in PATH and add new executables for suggestions
- Possibly more... see Issue page
Swell.sh will detect if the running program is NeoVim, and will hook into NeoVim's API to show autocomplete in the keyboard. The keyboard layout will also adjust for programming language input
** Requires NeoVim version 0.4.0+ **
coc.nvim and TabNine-vim are tested to work with Swell.sh (TabNine provides better autocomplete but is not open-source and requires lots of memory to run)
NOTE:
- only nvim is supported, vim is NOT supported due to lack of needed API
- if nvim is not detected (you get error message in Web UI or server log), you can also try specifying the NeoVim listening UNIX socket explicitly by
nvim --listen /some/abs/path <file>
, note you must specify an absolute path (eg:mktemp -u
) for the unix socket, relative path won't work - for Termux and Android 10+, you must use
--listen
for it to work
If your system NeoVim installation does not work with Swell.sh, you can optionally install it separately under the repo directory (NOT applicable to Termux):
- Download latest NeoVim
nvim-linux64.tar.gz
from https://github.com/neovim/neovim/releases into the repo root and extract it - Install TabNine-vim or coc.nvim by cloning into
./nvim-linux64/
- coc.nvim requires node.js and npm, and you need to run
npm install
in./nvim-linux64/coc.nvim
after cloning to finish the installtion
- coc.nvim requires node.js and npm, and you need to run
- Edit
./nvim-linux64/init.vim
and add your vim settings - Run Swell.sh with
./run-with-env.sh
, this script will add./nvim-linux64/bin
to PATH and use./nvim-linux64/init.vim
as the NeoVim config, so that it will not interfere with your global NeoVim config - If you use Tmux and run Swell.sh with
./run-with-env.sh
, you will need to addset-option -ga update-environment ' PATH VIMINIT'
to~/.tmux.conf
for the env vars to be passed down to the bash spawned by Tmux, PS changing tmux.conf requires killing all existing sessions and restart Tmux for the new settings to take effect
NOTE: if you are using Tmux in Termux on Android, you do not need to apply the cap_sys_ptrace
setting below
If you want the autocomplete suggestion to work for bash inside Tmux, please do the following:
-
(you can skip this if your
ptrace_scope
is 0) Add the capabilitycap_sys_ptrace
to the python interpreter in your virtualenv, by:sudo setcap cap_sys_ptrace=eip <path to python interpreter like venv/bin/python3>
(If you do not havesetcap
command, please google how to install on your system) -
Attach to the tmux session by this command:
tmux a -t <session name>
NOTE: you have to attach to the tmux session using the above command in order for Swell.sh to work.
If you create a new session, please detach from it then re-attach to it using the above command. Otherwise the autocomplete suggestion bar will not update.
Tips:
- Adding
set -g mouse on
to your~/.tmux.conf
to allow touch in Tmux, useful for switching between windows/panes - You can long-press 'n' or 'p' key to quickly switch between next/previous window
NOTE: Termux is only tested on the Android devices I have access to (Android Pie/9), and requires 64-bit device
Swell.sh could also be used as an alternative front-end for Termux Bash shell on Android
-
Install
Python3
,bash-completion
in Termuxpkg install python bash-completion
For
bash-completion
to work, please addsource /data/data/com.termux/files/usr/share/bash-completion/bash_completion
(actual path tobash_completion
script maybe different on your device, you have to find that out) to your~/.bashrc
(create one if not exist) -
Swell.sh depends on Android
libc.so
, if you get an error saying libc not found, please add the directory which contain thelibc.so
file toLD_LIBRARY_PATH
by egexport LD_LIBRARY_PATH=/system/lib64/:$LD_LIBRARY_PATH
in~/.bashrc
(eg:/system/lib64/
, you can find that directory path by looking at the rightmost column of the commandcat /proc/$$/maps | grep libc
in a Termux Bash shell) -
To install and run:
Similar to above, wget/git clone the source repo into a directory, create a
venv
(On Termux, you can create virtual env bypython -m venv venv
), activate it,pip install -r requirements.txt
, then runpython app.py
Then go to
localhost:<PORT>
in Chrome -
If you want to work with Tmux on Termux,
-
Attach to the tmux session by this command:
tmux a -t <session name>
NOTE: you have to attach to the tmux session using the above command in order for Swell.sh to work.
If you create a new session, please detach from it then re-attach to it using the above command. Otherwise the autocomplete suggestion bar will not update.
-
The setcap
/ptrace_scope
in the above section does not apply to Termux
A: Swipe up from space bar
A: Swiping left of Backspace key sends CTRL-W, useful for deleting the suggested word when none of the swipe gesture candidates are correct
A: Swipe up/down/left/right the cursor key (✥) to input up/down/left/right respectively. If swiping down is not detected on your phone, you can also long press that key to input "Down Arrow". Tapping the key will input "Left Arrow"
A: Click 'ctrl', when that key changes to 'CTRL' press the desired alphabet to input Ctrl+alphabet
A: Click ⇧ (Shift) to switch layout to Uppercase, then click 'alt', when that key changes to 'ALT' press the desired alphabet to input Alt+alphabet
A: Click a key 'T+'
A: Click '🌐' Key then input in the text box using the mobile OS's keyboard
A: Try changing font size or running the resize
/resizecons
command, which could be obtained from kbd
package on Ubuntu
- Double tap to select the text, it will be automatically copied to clipboard (Chrome only)
- Click '✂️' key, it will pop up the terminal text content in a new window where you can select text to copy (limitation: control characters are also in the output)
- Click '📋' key (Works only on Chrome and must be https/localhost)
- Click '🌐' Key then input in the text box
- You can also drag text from another window onto the terminal to paste text (eg: using Tablet split screens)
- You can to set the Bash prompt to shorter for more space for typing the commands, by
export PS1='$ '
- If you are using Android Chrome, you can use "Add to Home screen" (from the hamburger menu) to add a shortcut to the web app, this allows launching without the address bar to save more screen space
See ACKNOWLEDGEMENT.md
Copyright (c) 2019 - 2020 Choi Wai Chung
AGPL version 3