#!/bin/sh set -e if [ ! -n "$1" ]; then echo "usage: $(basename $0) " exit 0 fi # if this is running on an interactive # terminal (as opposed to in a script), if tput is installed, and if tput # knows some color codes, then set the color values. if [ -t 1 ] && [ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ]; then _clr="$(tput sgr0)" _red="$(tput setaf 1)" fi err() { echo "$_red[ERR]$_clr $@" >&2 exit 1 } tgt="$1" shift [ -d "$tgt" ] || err "no such directory as '$tgt'" [ "$(stat -Lt "$tgt")" != "$(stat -Lt "/")" ] \ || err "chroot target points to /! did something go wrong? exiting." # if the user already did some of the necessary prep, don't mess with it. [ -e "$tgt/proc" ] || export _proc="skip" [ -e "$tgt/dev" ] || export _dev="skip" [ -e "$tgt/sys" ] || export _sys="skip" [ -e "$tgt/tmp" ] || export _tmp="skip" [ -z "$_proc" ] || { mkdir "$tgt/proc" && mount -n -t proc proc "$tgt/proc"; } [ -z "$_dev" ] || { mkdir "$tgt/dev" && mount -o bind /dev "$tgt/dev"; } [ -z "$_sys" ] || { mkdir "$tgt/sys" && mount -n -t sysfs sys "$tgt/sys"; } [ -z "$_tmp" ] || { mkdir "$tgt/tmp" && mount -n -t tmpfs tmpfs "$tgt/tmp"; } cleanup() { [ -z "$_tmp" ] || { umount "$tgt/tmp" && rmdir "$tgt/tmp"; } [ -z "$_sys" ] || { umount "$tgt/sys" && rmdir "$tgt/sys"; } [ -z "$_dev" ] || { umount "$tgt/dev" && rmdir "$tgt/dev"; } [ -z "$_proc" ] || { umount "$tgt/proc" && rmdir "$tgt/proc"; } } trap cleanup EXIT INT HUP cd -- "$tgt" chroot . sh -c "$@" cd - >/dev/null