From 0d7e4fea9581f71fb14693f65a4e44fd10c1faf0 Mon Sep 17 00:00:00 2001 From: Sebastian Cabrera Date: Sat, 4 Jul 2026 03:44:20 -0400 Subject: [PATCH] add temp env script --- temp-env.sh | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 temp-env.sh diff --git a/temp-env.sh b/temp-env.sh new file mode 100644 index 0000000..ace43a5 --- /dev/null +++ b/temp-env.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +# +# temp-env.sh +# Spin up a throwaway Debian container, install packages, drop into a shell, +# and clean up automatically when you exit. + +set -euo pipefail + +# ---- colors ---- +BOLD='\033[1m' +CYAN='\033[0;36m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +RED='\033[0;31m' +NC='\033[0m' + +info() { echo -e "${CYAN}==>${NC} $1"; } +ok() { echo -e "${GREEN}✔${NC} $1"; } +warn() { echo -e "${YELLOW}!${NC} $1"; } +err() { echo -e "${RED}✘${NC} $1"; } + +# ---- sanity checks ---- +if ! command -v docker &>/dev/null; then + err "Docker isn't installed or isn't on PATH." + exit 1 +fi + +echo -e "${BOLD}Ephemeral Debian Environment${NC}" +echo "--------------------------------" + +# ---- pick a debian tag ---- +read -rp "$(echo -e "${CYAN}?${NC} Debian tag [bookworm]: ")" TAG +TAG="${TAG:-bookworm}" +IMAGE="debian:${TAG}" + +# ---- packages to install ---- +read -rp "$(echo -e "${CYAN}?${NC} Packages to install (space-separated, blank for none): ")" PACKAGES + +# ---- optional extra apt flags ---- +read -rp "$(echo -e "${CYAN}?${NC} Extra apt-get flags (e.g. --no-install-recommends) [none]: ")" APT_FLAGS + +# ---- mount a local dir? ---- +read -rp "$(echo -e "${CYAN}?${NC} Mount a local directory into the container? (path or blank): ")" MOUNT_DIR +MOUNT_ARGS=() +if [[ -n "$MOUNT_DIR" ]]; then + if [[ -d "$MOUNT_DIR" ]]; then + MOUNT_ARGS=(-v "$(realpath "$MOUNT_DIR"):/mnt/host") + ok "Will mount $(realpath "$MOUNT_DIR") -> /mnt/host" + else + warn "Directory '$MOUNT_DIR' doesn't exist, skipping mount." + fi +fi + +# ---- remove image after exit too? ---- +read -rp "$(echo -e "${CYAN}?${NC} Remove the image (${IMAGE}) after exiting, not just the container? [y/N]: ")" RM_IMAGE +RM_IMAGE="${RM_IMAGE:-n}" + +# ---- build the in-container command ---- +if [[ -n "$PACKAGES" ]]; then + INNER_CMD="apt-get update && apt-get install -y ${APT_FLAGS} ${PACKAGES} && bash" +else + INNER_CMD="apt-get update && bash" +fi + +echo +info "Image: ${IMAGE}" +info "Packages: ${PACKAGES:-}" +info "Command: ${INNER_CMD}" +[[ -n "$MOUNT_DIR" && -d "$MOUNT_DIR" ]] && info "Mount: $(realpath "$MOUNT_DIR") -> /mnt/host" +echo + +read -rp "$(echo -e "${CYAN}?${NC} Launch now? [Y/n]: ")" CONFIRM +CONFIRM="${CONFIRM:-y}" +if [[ ! "$CONFIRM" =~ ^[Yy] ]]; then + warn "Aborted." + exit 0 +fi + +info "Pulling/starting container (this shell disappears on exit, --rm is set)..." +echo "--------------------------------" + +set +e +docker run --rm -it "${MOUNT_ARGS[@]}" "$IMAGE" bash -c "$INNER_CMD" +EXIT_CODE=$? +set -e + +echo "--------------------------------" +ok "Container exited (code ${EXIT_CODE}) and was automatically removed." + +if [[ "$RM_IMAGE" =~ ^[Yy] ]]; then + info "Checking if any other containers still use ${IMAGE}..." + IN_USE=$(docker ps -a --filter ancestor="$IMAGE" -q) + if [[ -n "$IN_USE" ]]; then + warn "Other containers still reference ${IMAGE}, skipping removal:" + docker ps -a --filter ancestor="$IMAGE" + else + docker rmi "$IMAGE" && ok "Removed image ${IMAGE}." + fi +fi + +ok "Done."