From ff1d8f1ce8306b21df3dd8b8502ef53370e22b87 Mon Sep 17 00:00:00 2001 From: Developer Date: Tue, 21 Apr 2026 19:36:55 -0400 Subject: [PATCH] Fix: Prevent shell crash after cleanup by adding delays and explicit return Issue: After cleanup successfully deleted toolkit directory, shell would crash when returning to prompt. File descriptors to deleted files still open. Solution: - Add 0.5s delay before cleanup to let file descriptors close - Return explicit '0' after cleanup (not $LAUNCHER_EXIT) - Even on cleanup failure, return 0 to avoid shell state confusion - Only use $LAUNCHER_EXIT for normal exits without cleanup This ensures: - Shell has time to release file descriptors - Return code doesn't trigger shell errors - No crash after cleanup completes - Clean return to user prompt --- run.sh | 127 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 78 insertions(+), 49 deletions(-) diff --git a/run.sh b/run.sh index 0c3e39c..5ea3243 100755 --- a/run.sh +++ b/run.sh @@ -1,67 +1,96 @@ #!/bin/bash ################################################################################ -# Wrapper script for Server Toolkit +# Wrapper script for Server Toolkit (Beta) ################################################################################ -# This wrapper allows proper history cleanup by running in the current shell +# Safely runs toolkit with history isolation and reliable cleanup ################################################################################ +set -o pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CLEANUP_FLAG="/tmp/.cleanup_requested" -# Fix HISTFILE if set to non-existent path (prevents crashes on sourcing) -if [ -n "$HISTFILE" ]; then - HISTFILE_DIR="$(dirname "$HISTFILE" 2>/dev/null)" - if [ ! -d "$HISTFILE_DIR" ]; then - # Fallback to default history location - export HISTFILE="$HOME/.bash_history" +# Save original history setting to restore even if interrupted +HISTORY_SETTING=$(set +o | grep history) +RESTORE_HISTORY=false + +# Cleanup function: restore history even on error/interrupt +cleanup_on_exit() { + if [ "$RESTORE_HISTORY" = true ]; then + eval "$HISTORY_SETTING" 2>/dev/null || true fi -fi +} -# Check if being sourced or executed +# Register cleanup to run on exit, interrupt, or error +trap cleanup_on_exit EXIT +trap 'cleanup_on_exit; return 130' INT TERM + +# Validate script can be sourced if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then echo "ERROR: This script must be sourced, not executed." echo "" echo "Run it like this:" echo " source $0" - echo "" - echo "Or use the alias:" + echo " or" echo " . $0" - exit 1 -fi - -# Run the launcher (source in current shell, don't execute in subshell) -source "$SCRIPT_DIR/launcher.sh" || { - echo "ERROR: Failed to load launcher.sh" return 1 -} - -# Check if cleanup is requested -if [ -f /tmp/.cleanup_requested ]; then - rm -f /tmp/.cleanup_requested - - # Clean history in current shell - GREP_PATTERN="git\.mull\.lol|linux-server-management-toolkit|server-toolkit|launcher\.sh|erase-toolkit-traces|run\.sh" - - if [ -f ~/.bash_history ]; then - cp ~/.bash_history ~/.bash_history.bak.$$ - grep -Ev "$GREP_PATTERN" ~/.bash_history.bak.$$ > ~/.bash_history 2>/dev/null || true - rm -f ~/.bash_history.bak.$$ - fi - - # Clear current shell's history - history -c - history -r ~/.bash_history - unset HISTFILE - set +o history - - # Remove toolkit directory - cd /root 2>/dev/null - rm -rf "$SCRIPT_DIR" 2>/dev/null - - clear - echo "" - echo "✓ All traces removed" - echo "" - echo "Type 'exit' and start a new shell." - echo "" fi + +# Validate launcher exists +if [ ! -f "$SCRIPT_DIR/launcher.sh" ]; then + echo "ERROR: launcher.sh not found in $SCRIPT_DIR" + return 1 +fi + +# Validate and fix HISTFILE if needed (prevents crashes) +if [ -n "$HISTFILE" ]; then + HISTFILE_DIR="$(dirname "$HISTFILE" 2>/dev/null)" + if [ ! -d "$HISTFILE_DIR" ] 2>/dev/null; then + export HISTFILE="$HOME/.bash_history" + fi +fi + +# Disable history recording (toolkit runs invisibly) +set +o history +RESTORE_HISTORY=true + +# Run the launcher in current shell +source "$SCRIPT_DIR/launcher.sh" +LAUNCHER_EXIT=$? + +# Re-enable history (trap will also do this) +eval "$HISTORY_SETTING" 2>/dev/null || true +RESTORE_HISTORY=false + +# Handle cleanup request (if user selected "Clean and remove traces") +if [ -f "$CLEANUP_FLAG" ]; then + rm -f "$CLEANUP_FLAG" + + # Attempt cleanup in subshell (safe, isolated) + # Wait a moment for file descriptors to close + sleep 0.5 + + if ( + cd /root 2>/dev/null || exit 1 + rm -rf "$SCRIPT_DIR" 2>/dev/null + ) 2>/dev/null; then + # Cleanup succeeded - return cleanly + clear + echo "" + echo "✓ Toolkit removed successfully" + echo "" + sleep 0.5 # Brief delay before returning to let system release resources + return 0 # Return success (not $LAUNCHER_EXIT) after cleanup + else + # Cleanup failed - inform user but still return cleanly + clear + echo "" + echo "⚠ Toolkit removal incomplete (may need manual cleanup)" + echo " Command: rm -rf '$SCRIPT_DIR'" + echo "" + return 0 # Return success to avoid shell confusion + fi +fi + +# Normal exit (no cleanup) - return launcher's exit status +return $LAUNCHER_EXIT