diff --git a/docs/source/installation/troubleshooting-common.rst b/docs/source/installation/troubleshooting-common.rst
index 98abdd54..bb688d7e 100644
--- a/docs/source/installation/troubleshooting-common.rst
+++ b/docs/source/installation/troubleshooting-common.rst
@@ -132,3 +132,10 @@ To get rid of these lags there currently are two options:
   the future.
 * Compile and install ``libzpython`` module that lives in 
   https://bitbucket.org/ZyX_I/zpython. This variant is zsh-specific.
+
+Prompt is spoiled after completing files in ksh
+-----------------------------------------------
+
+This is exactly why powerline has official mksh support, but not official ksh 
+support. If you know the solution feel free to share it in `powerline bug 
+tracker <https://github.com/Lokaltog/powerline/issues/new>`_.
diff --git a/docs/source/overview.rst b/docs/source/overview.rst
index 23b16942..3b44268d 100644
--- a/docs/source/overview.rst
+++ b/docs/source/overview.rst
@@ -166,6 +166,38 @@ is the absolute path to your Powerline installation directory:
 
 .. _tmux-statusline:
 
+Busybox (ash), mksh and dash prompt
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+After launching busybox run the following command:
+
+.. code-block:: bash
+
+   . {repository_root}/powerline/bindings/shell/powerline.sh
+
+Mksh users may put this line into ``~/.mkshrc`` file. Dash users may use the 
+following in ``~/.profile``:
+
+.. code-block:: bash
+
+    if test "x$0" != "x${0#dash}" ; then
+        export ENV={repository_root}/powerline/bindings/shell/powerline.sh
+    fi
+
+.. note::
+    Dash users that already have ``$ENV`` defined should either put the ``. 
+    …/shell/powerline.sh`` line in the ``$ENV`` file or create a new file which 
+    will source (using ``.`` command) both former ``$ENV`` file and 
+    :file:`powerline.sh` files and set ``$ENV`` to the path of this new file.
+
+.. warning::
+    Job count is using some weird hack that uses signals and temporary files for 
+    interprocess communication. It may be wrong sometimes. Not the case in mksh.
+
+.. warning::
+    Busybox has two shells: ``ash`` and ``hush``. Second is known to segfault in 
+    busybox 1.22.1 when using :file:`powerline.sh` script.
+
 Tmux statusline
 ---------------
 
diff --git a/powerline/bindings/shell/powerline.sh b/powerline/bindings/shell/powerline.sh
new file mode 100644
index 00000000..6f45ffde
--- /dev/null
+++ b/powerline/bindings/shell/powerline.sh
@@ -0,0 +1,181 @@
+_powerline_columns_fallback() {
+	if which stty >/dev/null ; then
+		# Ksh does not have “local” built-in
+		_powerline_cols="$(stty size 2>/dev/null)"
+		if ! test -z "$_powerline_cols" ; then
+			echo "${_powerline_cols#* }"
+			return 0
+		fi
+	fi
+	echo 0
+	return 0
+}
+
+_powerline_has_jobs_in_subshell() {
+	if test -n "$_POWERLINE_HAS_JOBS_IN_SUBSHELL" ; then
+		return $_POWERLINE_HAS_JOBS_IN_SUBSHELL
+	elif test -z "$1" ; then
+		sleep 1 &
+		# Check whether shell outputs anything in a subshell when using jobs 
+		# built-in. Shells like dash will not output anything meaning that 
+		# I have to bother with temporary files.
+		test "$(jobs -p|wc -l)" -gt 0
+	else
+		case "$1" in
+			dash|bb|ash) return 1 ;;
+			mksh|ksh|bash) return 0 ;;
+			*) _powerline_has_jobs_in_subshell ;;
+		esac
+	fi
+	_POWERLINE_HAS_JOBS_IN_SUBSHELL=$?
+	return $_POWERLINE_HAS_JOBS_IN_SUBSHELL
+}
+
+_powerline_set_append_trap() {
+	if _powerline_has_jobs_in_subshell "$@" ; then
+		_powerline_append_trap() {
+			# Arguments: command, signal
+			# Ksh does not have “local” built-in
+			_powerline_traps="$(trap)"
+			if echo "$_powerline_traps" | grep -cm1 $2'$' >/dev/null ; then
+				_powerline_traps="$(echo "$_powerline_traps" | sed "s/ $2/'\\n$1' $2/")"
+				eval "$_powerline_traps"
+			fi
+		}
+	else
+		_powerline_append_trap() {
+			# Arguments: command, signal
+			_powerline_create_temp
+			trap > $_POWERLINE_TEMP
+			if grep -cm1 $2'$' $_POWERLINE_TEMP >/dev/null ; then
+				sed -i -e "s/ $2/'\\n$1' $2/"
+				. $_POWERLINE_TEMP
+			else
+				trap "$1" $2
+			fi
+			echo -n > $_POWERLINE_TEMP
+		}
+	fi
+	_powerline_set_append_trap() {
+		return 0
+	}
+}
+
+_powerline_create_temp() {
+	if test -z "$_POWERLINE_TEMP" || ! test -e "$_POWERLINE_TEMP" ; then
+		_POWERLINE_TEMP="$(mktemp)"
+		_powerline_append_trap 'rm $_POWERLINE_TEMP' EXIT
+	fi
+}
+
+_powerline_set_set_jobs() {
+	if _powerline_has_jobs_in_subshell "$@" ; then
+		_powerline_set_jobs() {
+			_POWERLINE_JOBS="$(jobs -p|wc -l)"
+		}
+	else
+		_powerline_set_append_trap "$@"
+		_POWERLINE_PID=$$
+		_powerline_append_trap '_powerline_do_set_jobs' USR1
+		_powerline_do_set_jobs() {
+			_powerline_create_temp
+			jobs -p > $_POWERLINE_TEMP
+		}
+		# This command will always be launched from a subshell, thus a hack is 
+		# needed to run `jobs -p` outside of the subshell.
+		_powerline_set_jobs() {
+			kill -USR1 $_POWERLINE_PID
+			# Note: most likely this will read data from the previous run. Tests 
+			# show that it is OK for some reasons.
+			_POWERLINE_JOBS="$(wc -l < $_POWERLINE_TEMP)"
+		}
+	fi
+	_powerline_set_set_jobs() {
+		return 0
+	}
+}
+
+_powerline_set_command() {
+	if test -z "${POWERLINE_COMMAND}" ; then
+		if which powerline-client >/dev/null ; then
+			export POWERLINE_COMMAND=powerline-client
+		elif which powerline >/dev/null ; then
+			export POWERLINE_COMMAND=powerline
+		else
+			# `$0` is set to `-bash` when using SSH so that won't work
+			export POWERLINE_COMMAND="$(dirname "$BASH_SOURCE")/../../../scripts/powerline"
+		fi
+	fi
+}
+
+_powerline_tmux_setenv() {
+	TMUX="$_POWERLINE_TMUX" tmux setenv -g TMUX_"$1"_`tmux display -p "#D" | tr -d %` "$2"
+	TMUX="$_POWERLINE_TMUX" tmux refresh -S
+}
+
+_powerline_tmux_set_pwd() {
+	if test "x$_POWERLINE_SAVED_PWD" != "x$PWD" ; then
+		_POWERLINE_SAVED_PWD="$PWD"
+		_powerline_tmux_setenv PWD "$PWD"
+	fi
+}
+
+_powerline_tmux_set_columns() {
+	_powerline_tmux_setenv COLUMNS "${COLUMNS:-$(_powerline_columns_fallback)}"
+}
+
+_powerline_set_renderer_arg() {
+	case "$1" in
+		bb|ash) _POWERLINE_RENDERER_ARG="-rbash_prompt" ;;
+		mksh|ksh) _POWERLINE_RENDERER_ARG="-rksh_prompt" ;;
+		bash|dash) _POWERLINE_RENDERER_ARG= ;;
+	esac
+}
+
+_powerline_set_jobs() {
+	_powerline_set_set_jobs
+	_powerline_set_jobs
+}
+
+_powerline_prompt() {
+	# Arguments: side, exit_code
+	_powerline_set_jobs
+	$POWERLINE_COMMAND shell $1 -w "${COLUMNS:-$(_powerline_columns_fallback)}" $_POWERLINE_RENDERER_ARG --last_exit_code=$2 --jobnum=$_POWERLINE_JOBS
+}
+
+_powerline_setup_prompt() {
+	VIRTUAL_ENV_DISABLE_PROMPT=1
+	_powerline_set_append_trap "$@"
+	_powerline_set_set_jobs "$@"
+	_powerline_set_command "$@"
+	_powerline_set_renderer_arg "$@"
+	PS1='$(_powerline_prompt aboveleft $?)'
+}
+
+_powerline_init_tmux_support() {
+	# Dash does not have &>/dev/null
+	if test -n "$TMUX" && tmux refresh -S >/dev/null 2>/dev/null ; then
+		# TMUX variable may be unset to create new tmux session inside this one
+		_POWERLINE_TMUX="$TMUX"
+
+		_powerline_set_append_trap "$@"
+
+		# If _powerline_tmux_set_pwd is used before _powerline_prompt it sets $? 
+		# to zero in ksh.
+		PS1="$PS1"'$(_powerline_tmux_set_pwd)'
+		_powerline_append_trap '_powerline_tmux_set_columns' WINCH
+		_powerline_tmux_set_columns
+	fi
+}
+
+# Strips the leading `-`: it may be present when shell is a login shell
+_POWERLINE_USED_SHELL=${0#-}
+_POWERLINE_USED_SHELL=${_POWERLINE_USED_SHELL#/usr}
+_POWERLINE_USED_SHELL=${_POWERLINE_USED_SHELL#/bin/}
+
+if test -z "$POWERLINE_NO_BB_PROMPT$POWERLINE_NO_SHELL_PROMPT" ; then
+	_powerline_setup_prompt $_POWERLINE_USED_SHELL
+fi
+if test -z "$POWERLINE_NO_BB_TMUX_SUPPORT$POWERLINE_NO_SHELL_TMUX_SUPPORT" ; then
+	_powerline_init_tmux_support $_POWERLINE_USED_SHELL
+fi
diff --git a/powerline/renderers/ksh_prompt.py b/powerline/renderers/ksh_prompt.py
new file mode 100644
index 00000000..3b4387a4
--- /dev/null
+++ b/powerline/renderers/ksh_prompt.py
@@ -0,0 +1,20 @@
+# vim:fileencoding=utf-8:noet
+
+from __future__ import absolute_import, unicode_literals
+
+from powerline.renderers.shell import ShellRenderer
+
+
+ESCAPE_CHAR = '\001'
+
+
+class KshPromptRenderer(ShellRenderer):
+	'''Powerline bash prompt segment renderer.'''
+	escape_hl_start = '\001'
+	escape_hl_end = '\001'
+
+	def render(self, *args, **kwargs):
+		return '\001\r' + super(KshPromptRenderer, self).render(*args, **kwargs)
+
+
+renderer = KshPromptRenderer
diff --git a/tests/install.sh b/tests/install.sh
index 05d2e3d2..1f1a3729 100755
--- a/tests/install.sh
+++ b/tests/install.sh
@@ -12,7 +12,7 @@ if python -c 'import sys; sys.exit(1 * (sys.version_info[0] != 2))' ; then
 		pip install unittest2 argparse
 	fi
 fi
-sudo apt-get install -qq screen zsh tcsh
+sudo apt-get install -qq screen zsh tcsh mksh busybox
 # Travis has too outdated fish. It cannot be used for tests.
 # sudo apt-get install fish
 true
diff --git a/tests/test.sh b/tests/test.sh
index 5ea9d0ea..f25d63a6 100755
--- a/tests/test.sh
+++ b/tests/test.sh
@@ -20,7 +20,7 @@ for script in tests/*.vim ; do
 		FAILED=1
 	fi
 done
-if ! sh tests/test_shells/test.sh ; then
+if ! bash tests/test_shells/test.sh ; then
 	echo "Failed shells"
 	if ${PYTHON} -c 'import platform, sys; sys.exit(1 * (platform.python_implementation() == "PyPy"))' ; then
 		FAILED=1
diff --git a/tests/test_shells/bb.ok b/tests/test_shells/bb.ok
new file mode 100644
index 00000000..8a439c05
--- /dev/null
+++ b/tests/test_shells/bb.ok
@@ -0,0 +1,17 @@
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd .git
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  .git  cd ..
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
+  HOSTNAME  USER  ⓔ  some-virtual-environment   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV=
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s
+[1]+  Terminated                 bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done"
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  cd "$DIR1"
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^[[32m  cd ../"$DIR2"
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^H  cd ../'\[\]'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  \[\]  cd ../'%%'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  %%  cd ../'#[bold]'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  false
diff --git a/tests/test_shells/dash.ok b/tests/test_shells/dash.ok
new file mode 100644
index 00000000..2a42cd64
--- /dev/null
+++ b/tests/test_shells/dash.ok
@@ -0,0 +1,17 @@
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd .git
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  .git  cd ..
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
+  HOSTNAME  USER  ⓔ  some-virtual-environment   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV=
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1s
+[1] + Terminated                 bash -c "echo \$\$>pid ; while true ; do sleep 0.1s ; done"
+cd "$DIR1"
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1    HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^[[32m  cd ../"$DIR2"
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^H  cd ../'\[\]'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  \[\]  cd ../'%%'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  %%  cd ../'#[bold]'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  false
diff --git a/tests/test_shells/input.bash b/tests/test_shells/input.bash
index 3a95d3a1..748e78fa 100644
--- a/tests/test_shells/input.bash
+++ b/tests/test_shells/input.bash
@@ -1,7 +1,7 @@
 POWERLINE_COMMAND="$PWD/scripts/powerline -p $PWD/powerline/config_files"
 POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
 POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
-VIRTUAL_ENV=
+export VIRTUAL_ENV=
 source powerline/bindings/bash/powerline.sh ; cd tests/shell/3rd
 cd .git
 cd ..
diff --git a/tests/test_shells/input.bb b/tests/test_shells/input.bb
new file mode 100644
index 00000000..d9ae1342
--- /dev/null
+++ b/tests/test_shells/input.bb
@@ -0,0 +1,23 @@
+POWERLINE_COMMAND="$PWD/scripts/powerline -p $PWD/powerline/config_files"
+POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
+POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
+export VIRTUAL_ENV=
+. powerline/bindings/shell/powerline.sh ; cd tests/shell/3rd
+cd .git
+cd ..
+VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
+VIRTUAL_ENV=
+bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
+false
+kill `cat pid` ; sleep 1s
+cd "$DIR1"
+cd ../"$DIR2"
+cd ../'\[\]'
+cd ../'%%'
+cd ../'#[bold]'
+cd ../'(echo)'
+cd ../'$(echo)'
+cd ../'`echo`'
+false
+true is the last line
+exit
diff --git a/tests/test_shells/input.dash b/tests/test_shells/input.dash
new file mode 100644
index 00000000..d9ae1342
--- /dev/null
+++ b/tests/test_shells/input.dash
@@ -0,0 +1,23 @@
+POWERLINE_COMMAND="$PWD/scripts/powerline -p $PWD/powerline/config_files"
+POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
+POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
+export VIRTUAL_ENV=
+. powerline/bindings/shell/powerline.sh ; cd tests/shell/3rd
+cd .git
+cd ..
+VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
+VIRTUAL_ENV=
+bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
+false
+kill `cat pid` ; sleep 1s
+cd "$DIR1"
+cd ../"$DIR2"
+cd ../'\[\]'
+cd ../'%%'
+cd ../'#[bold]'
+cd ../'(echo)'
+cd ../'$(echo)'
+cd ../'`echo`'
+false
+true is the last line
+exit
diff --git a/tests/test_shells/input.fish b/tests/test_shells/input.fish
index afb3df3b..3e69ad5e 100644
--- a/tests/test_shells/input.fish
+++ b/tests/test_shells/input.fish
@@ -1,13 +1,13 @@
 set POWERLINE_COMMAND "$PWD/scripts/powerline -p $PWD/powerline/config_files"
 set POWERLINE_COMMAND "$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
 set POWERLINE_COMMAND "$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
-set VIRTUAL_ENV
+setenv VIRTUAL_ENV
 set fish_function_path $fish_function_path "$PWD/powerline/bindings/fish"
 powerline-setup ; cd tests/shell/3rd
 cd .git
 cd ..
-set VIRTUAL_ENV "$HOME/.virtenvs/some-virtual-environment"
-set VIRTUAL_ENV
+setenv VIRTUAL_ENV "$HOME/.virtenvs/some-virtual-environment"
+setenv VIRTUAL_ENV
 bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
 false
 kill (cat pid) ; sleep 1s
diff --git a/tests/test_shells/input.mksh b/tests/test_shells/input.mksh
new file mode 100644
index 00000000..a4a5928a
--- /dev/null
+++ b/tests/test_shells/input.mksh
@@ -0,0 +1,23 @@
+POWERLINE_COMMAND="$PWD/scripts/powerline -p $PWD/powerline/config_files"
+POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
+POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
+export VIRTUAL_ENV=
+. powerline/bindings/shell/powerline.sh ; cd tests/shell/3rd
+cd .git
+cd ..
+VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
+VIRTUAL_ENV=
+bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
+false
+kill `cat pid` ; sleep 1
+cd "$DIR1"
+cd ../"$DIR2"
+cd ../'\[\]'
+cd ../'%%'
+cd ../'#[bold]'
+cd ../'(echo)'
+cd ../'$(echo)'
+cd ../'`echo`'
+false
+true is the last line
+exit
diff --git a/tests/test_shells/input.zsh b/tests/test_shells/input.zsh
index 5beb8517..b40c3283 100644
--- a/tests/test_shells/input.zsh
+++ b/tests/test_shells/input.zsh
@@ -2,7 +2,12 @@ unsetopt promptsp transientrprompt
 POWERLINE_COMMAND=( $PWD/scripts/powerline -p $PWD/powerline/config_files )
 POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false )
 POWERLINE_COMMAND=( $POWERLINE_COMMAND -c ext.shell.theme=default_leftonly )
-VIRTUAL_ENV=
+setopt interactivecomments
+# POWERLINE_CONFIG_PATH=$PWD/powerline/config_files
+# POWERLINE_THEME_CONFIG=( default_leftonly.segment_data.hostname.args.only_if_ssh=false )
+# POWERLINE_CONFIG=( ext.shell.theme=default_leftonly )
+POWERLINE_NO_ZSH_ZPYTHON=1  # TODO: make tests work with zsh/zpython
+export VIRTUAL_ENV=
 source powerline/bindings/zsh/powerline.zsh ; cd tests/shell/3rd
 cd .git
 cd ..
diff --git a/tests/test_shells/mksh.ok b/tests/test_shells/mksh.ok
new file mode 100644
index 00000000..09307716
--- /dev/null
+++ b/tests/test_shells/mksh.ok
@@ -0,0 +1,19 @@
+
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd .git
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  .git  cd ..
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV="$HOME/.virtenvs/some-virtual-environment"
+  HOSTNAME  USER  ⓔ  some-virtual-environment   BRANCH  ⋯  tests  shell  3rd  VIRTUAL_ENV=
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  bash -c 'echo $$>pid ; while true ; do sleep 0.1s ; done' &
+[1] PID
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  false
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  1  1  kill `cat pid` ; sleep 1
+[1] + Terminated bash -c ...
+  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  cd "$DIR1"
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^[[32m  cd ../"$DIR2"
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  ^H  cd ../'\[\]'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  \[\]  cd ../'%%'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  %%  cd ../'#[bold]'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
+  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  false
diff --git a/tests/test_shells/postproc.py b/tests/test_shells/postproc.py
index 8d85917c..ce68c9d5 100755
--- a/tests/test_shells/postproc.py
+++ b/tests/test_shells/postproc.py
@@ -48,4 +48,9 @@ with codecs.open(fname, 'r', encoding='utf-8') as R:
 					line = line[start:end] + '\033[0m\n'
 				except ValueError:
 					line = ''
+			elif shell == 'mksh':
+				# Output is different in travis: on my machine I see full 
+				# command, in travis it is truncated just after `true`.
+				if line.startswith('[1] + Terminated'):
+					line = '[1] + Terminated bash -c ...\n'
 			W.write(line)
diff --git a/tests/test_shells/test.sh b/tests/test_shells/test.sh
index 9e9c370b..82f17f71 100755
--- a/tests/test_shells/test.sh
+++ b/tests/test_shells/test.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 FAILED=0
 ONLY_SHELL="$1"
 
@@ -16,20 +16,44 @@ check_screen_log() {
 run_test() {
 	SH="$1"
 	SESNAME="powerline-shell-test-${SH}-$$"
+	ARGS=( "$@" )
 
 	test "x$ONLY_SHELL" = "x" || test "x$ONLY_SHELL" = "x$SH" || return 0
 
-	which "${SH}" || return 0
+	if ! which "${SH}" ; then
+		if test "x${SH}" = "xbb" ; then
+			if ! which busybox ; then
+				return 0
+			fi
+			shift
+			ARGS=( busybox ash "$@" )
+		else
+			return 0
+		fi
+	fi
 
 	export SH
 
 	screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \
-		env LANG=en_US.UTF-8 BINDFILE="$BINDFILE" "$@"
+		env LANG=en_US.UTF-8 BINDFILE="$BINDFILE" "${ARGS[@]}"
 	screen -S "$SESNAME" -X readreg a tests/test_shells/input.$SH
 	# Wait for screen to initialize
-	sleep 1s
+	sleep 1
 	screen -S "$SESNAME" -p 0 -X width 300 1
-	screen -S "$SESNAME" -p 0 -X paste a
+	if test "x${SH}" = "xdash" ; then
+		# If I do not use this hack for dash then output will look like
+		#
+		#     command1
+		#     command2
+		#     …
+		#     prompt1> prompt2> …
+		while read -r line ; do
+			screen -S "$SESNAME" -p 0 -X stuff "$line"$'\n'
+			sleep 1
+		done < tests/test_shells/input.$SH
+	else
+		screen -S "$SESNAME" -p 0 -X paste a
+	fi
 	# Wait for screen to exit (sending command to non-existing screen session 
 	# fails; when launched instance exits corresponding session is deleted)
 	while screen -S "$SESNAME" -X blankerprg "" > /dev/null ; do
@@ -51,7 +75,23 @@ run_test() {
 		echo '============================================================'
 		cat -v tests/shell/${SH}.full.log
 		echo '____________________________________________________________'
-		${SH} --version
+		case ${SH} in
+			*ksh)
+				${SH} -c 'echo ${KSH_VERSION}'
+				;;
+			dash)
+				# ?
+				;;
+			bb)
+				bb --help
+				;;
+			*)
+				${SH} --version
+				;;
+		esac
+		if which dpkg >/dev/null ; then
+			dpkg -s ${SH}
+		fi
 		return 1
 	fi
 	return 0
@@ -90,5 +130,19 @@ if ! run_test tcsh -f -i ; then
 	FAILED=1
 fi
 
+if ! run_test bb -i ; then
+	FAILED=1
+fi
+
+unset ENV
+
+if ! run_test mksh -i ; then
+	FAILED=1
+fi
+
+if ! run_test dash -i ; then
+	FAILED=1
+fi
+
 test "x$ONLY_SHELL" = "x" && rm -r tests/shell
 exit $FAILED