Created
February 20, 2022 02:49
-
-
Save JackZielke/7c83a151c8075651b186921fc489f68e to your computer and use it in GitHub Desktop.
Create a BusyBox based Emergency Shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Archive.org version of the original page.