Skip to content

Instantly share code, notes, and snippets.

@JackZielke
Created February 20, 2022 02:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JackZielke/7c83a151c8075651b186921fc489f68e to your computer and use it in GitHub Desktop.
Save JackZielke/7c83a151c8075651b186921fc489f68e to your computer and use it in GitHub Desktop.
Create a BusyBox based Emergency Shell
#!/bin/bash
###########################################################################
### Creates a BusyBox emergency shell in RAM
###
### Script by Jack Zielke <eshell@linuxcoffee.com>
### http://linuxcoffee.com/eshell
###
### BusyBox is maintained by Denys Vlasenko, and licensed under the GNU
### GENERAL PUBLIC LICENSE version 2.
### http://www.busybox.net/
###########################################################################
###
### THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND.
###
###########################################################################
### @version $Id: eshell.sh 258 2012-09-13 15:18:18Z jzielke $
###########################################################################
# Options are ramfs, tmpfs
# tmpfs can be swapped, ramfs will not be swapped
TYPE=ramfs
# These are used for creating and locating the permanent RAM disk
PERM_DIR=/mnt/eshell
PERM_BB=/bin/busybox
echo
make_ramdisk() {
echo 'Calculating space'
read SIZE < <("$1" du "$1")
SIZE="${SIZE%% $1}" # That is a tab
# Provide a few k for wiggle room
SIZE=$[SIZE+9]
read ID < <("$1" id -u)
echo 'Creating '$SIZE'k RAM disk in '$2
if [ $ID -eq 0 ]; then
"$1" mount -t "$TYPE" -o size=${SIZE}k,mode=755 "$TYPE" "$2"
else
sudo "$1" mount -t "$TYPE" -o size=${SIZE}k,mode=755,uid=$ID "$TYPE" "$2"
if [ "$TYPE" == "ramfs" ]; then
sudo "$1" chown "$ID" "$2"
fi
fi
}
make_env() {
"$1" cp "$1" "$2/busybox"
echo 'Creating .profile'
echo alias rootsh=\'sudo env PATH=\"\$PATH\" busybox ash\' >"$2/.profile"
echo alias >>"$2/.profile"
echo echo \'exit to cleanup\' >>"$2/.profile"
echo echo \'rootsh for a root shell\' >>"$2/.profile"
echo echo >>"$2/.profile"
echo 'Building symlinks'
cd "$2"
{ { ./busybox --list 2>/dev/null; } || { ./busybox --help | ./busybox sed -n '/Currently defined functions:/,$p' | ./busybox grep -v 'Currently defined functions:' | ./busybox tr -d ' \t\n' | ./busybox tr , '\n' | ./busybox grep -v 'busybox'; }; } | ./busybox xargs -n 1 ./busybox ln -s busybox
}
setup_eshell() {
# Check if RAM disk is already mounted
read OUTPUT < <($PERM_BB grep -- "$PERM_DIR" /proc/mounts)
if [ -z "$OUTPUT" ]; then
echo 'Creating eshell RAM disk'
"$PERM_BB" mkdir -p "$PERM_DIR"
make_ramdisk "$PERM_BB" "$PERM_DIR"
fi
make_env "$PERM_BB" "$PERM_DIR"
}
check_tty () {
echo 'Checking for tty'
"$1" tty >/dev/null
if [ $? -ne 0 ]; then
echo 'No tty found, did you mean to ssh -t ?'
echo 'Press ctrl-c to stop or enter to continue'
read JUNK
fi
}
check_fallback() {
read OUTPUT < <("$1" true 2>&1 >&-)
if [ "$OUTPUT" == 'Using fallback suid method' ]; then
echo 'To suppress "Using fallback suid method" warnings, as root:'
echo 'touch /etc/busybox.conf'
echo
fi
}
run_eshell() {
check_fallback "$1/busybox"
cd /
export PATH="$1:$PATH"
echo 'Starting shell'
ENV="$1/.profile" "$1/busybox" ash
echo
}
show_help() {
echo 'eshell creates a BusyBox emergency shell in RAM.
There are 3 ways to use eshell.
1) eshell
Without any parameters:
This will set your PATH and run busybox ash as your shell.
If a permanent RAM disk was previously setup it will be used.
sudo access is required if the permanent RAM disk is not already set up.
sudo is not part of busybox. Run rootsh to sudo to root and retain
the eshell PATH.
2) eshell <busybox>
With the path to busybox as the parameter:
This is useful if you have downloaded busybox and it is not in your path
or you want to use a binary other than the first busybox in your path.
If the path to busybox is provided the permanent shell will not be used.
3) eshell setup
This will setup eshell in '$PERM_DIR' for later use.
Run eshell setup from your system startup scripts.
'
check_fallback busybox
}
if [ "$1" == '--help' -o "$1" == '-h' ]; then
show_help
exit
elif [ "$1" == "setup" ]; then
setup_eshell
exit
elif [ $# -eq 0 -a -e "$PERM_DIR/busybox" ]; then
echo 'Using permanent RAM disk in '$PERM_DIR
check_tty "$PERM_DIR/busybox"
run_eshell "$PERM_DIR"
exit
elif [ $# -eq 0 ]; then
echo 'Locating busybox'
read BB < <(command -v busybox)
else
echo 'Using '$*' for busybox binary'
BB="$*"
fi
if [ -n "$BB" ]; then
# Should check that $BB is actually a busybox binary
check_tty "$BB"
echo 'Creating temp directory'
read TMPDIR < <($BB mktemp -td 2>/dev/null || $BB mktemp -d /tmp/tmp.XXXXXX)
make_ramdisk "$BB" "$TMPDIR"
make_env "$BB" "$TMPDIR"
run_eshell "$TMPDIR"
echo 'Cleaning up'
sudo "$BB" umount "$TMPDIR"
"$BB" rmdir "$TMPDIR"
else
echo >&2
echo 'Error: Could not find busybox in '$PATH >&2
echo 'Rerun '$0' providing the path to busybox as an argument' >&2
echo 'Use -h or --help for help' >&2
echo >&2
exit 1
fi
@JackZielke
Copy link
Author

Archive.org version of the original page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment