Last active
September 21, 2026 06:37
-
-
Save hereisderek/8f41efc72e5b2f60b1089041bb1fc388 to your computer and use it in GitHub Desktop.
asciinema auto record shell
This file contains hidden or 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
| # Define the alias for ALL shells so you can use it inside the recording | |
| alias term-record="~/.config/asciinema/auto_asciinema.sh" | |
| # Optional: Ensure it's executable (only needs to be run once, but fine to leave here) | |
| chmod +x ~/.config/asciinema/auto_asciinema.sh | |
| # Start Asciinema Auto-Record wrapper ONLY if attached to a real TTY (-t 0) | |
| if [[ $- == *i* && -z "$ASCIINEMA_REC" && -t 0 ]]; then | |
| ~/.config/asciinema/auto_asciinema.sh auto | |
| # Close the outer shell window cleanly when the inner recording shell exits | |
| [ $? -eq 0 ] && exit | |
| fi | |
| # alias term-record="~/.config/asciinema/auto_asciinema.sh"; chmod +x ~/.config/asciinema/auto_asciinema.sh; [[ $- == *i* && -z "$ASCIINEMA_REC" && -t 0 ]] && ~/.config/asciinema/auto_asciinema.sh auto && exit |
This file contains hidden or 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
| #!/usr/bin/env bash | |
| # ========================================== | |
| # Configuration (Easily Modifiable Constants) | |
| # ========================================== | |
| RECORD_DIR="${HOME}/.config/asciinema/records" | |
| PENDING_DIR="${HOME}/.config/asciinema/pending_upload" | |
| AUTO_SAVE_DIR="${HOME}/.config/asciinema/auto_save" | |
| DEFAULT_FILENAME="$(hostname)_$(date +%Y%m%d_%H%M%S).cast" | |
| # ========================================== | |
| # Help Menu | |
| # ========================================== | |
| show_help() { | |
| cat << 'EOF' | |
| Usage: term-record [command] [options] | |
| Commands: | |
| auto Start auto-recording (use in your shell profile) | |
| save [name] [local|upload] Stop recording, save the cast, and KEEP the terminal open | |
| -h, --help Show this help message | |
| Examples: | |
| term-record save # Saves current session with default name and stops recording | |
| term-record save my_script # Saves as my_script.cast locally and stops recording | |
| term-record save my_script upload # Uploads session to asciinema.org and stops recording | |
| EOF | |
| } | |
| # ========================================== | |
| # Script Logic | |
| # ========================================== | |
| # Show help if requested or if no arguments are provided | |
| if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then | |
| show_help | |
| exit 0 | |
| fi | |
| # The interactive command to save/upload the session | |
| if [ "$1" = "save" ]; then | |
| if [ -z "$ASCIINEMA_REC" ] || [ -z "$ASCIINEMA_OUTER_PID" ]; then | |
| echo "Error: Not currently in an auto-recorded asciinema session." | |
| exit 1 | |
| fi | |
| INTENT_NAME="${2:-$DEFAULT_FILENAME}" | |
| INTENT_DEST="${3:-local}" | |
| # Save intent for the wrapper, adding a KEEP_OPEN flag | |
| echo "${INTENT_NAME}|${INTENT_DEST}|KEEP_OPEN" > "/tmp/asciinema_intent_$ASCIINEMA_OUTER_PID" | |
| echo "Stopping recording..." | |
| echo "File will be processed as '${INTENT_NAME}' for '${INTENT_DEST}'." | |
| # Kill the parent process (the inner shell) to seamlessly end the asciinema recording | |
| kill -HUP $PPID | |
| exit 0 | |
| fi | |
| # The automated wrapper logic | |
| if [ "$1" = "auto" ]; then | |
| # 1. Install check | |
| if ! command -v asciinema >/dev/null 2>&1; then | |
| echo "asciinema is not installed, but auto-recording is enabled." | |
| printf "Would you like to install it now? (y/n): " | |
| read -r REPLY < /dev/tty | |
| if [[ $REPLY =~ ^[Yy]$ ]]; then | |
| if command -v apt-get >/dev/null 2>&1; then | |
| sudo apt-get update && sudo apt-get install -y asciinema | |
| elif command -v brew >/dev/null 2>&1; then | |
| brew install asciinema | |
| elif command -v pacman >/dev/null 2>&1; then | |
| sudo pacman -S --noconfirm asciinema | |
| elif command -v dnf >/dev/null 2>&1; then | |
| sudo dnf install -y asciinema | |
| else | |
| echo "Could not detect package manager. Please install asciinema manually." | |
| fi | |
| fi | |
| if ! command -v asciinema >/dev/null 2>&1; then | |
| echo "Skipping auto-record for this session (asciinema not installed)." | |
| exit 2 | |
| fi | |
| fi | |
| # 2. Setup directories | |
| mkdir -p "$RECORD_DIR" "$PENDING_DIR" "$AUTO_SAVE_DIR" | |
| # 3. Process pending uploads from previous network drops | |
| for pending in "$PENDING_DIR"/*.cast; do | |
| [ -e "$pending" ] || continue | |
| echo "Uploading pending session: $(basename "$pending")..." | |
| if asciinema upload "$pending" >/dev/null 2>&1; then | |
| echo "Upload successful." | |
| rm -f "$pending" | |
| else | |
| echo "Upload still failing, will retry next time." | |
| fi | |
| done | |
| # 4. Setup current session | |
| export ASCIINEMA_OUTER_PID=$$ | |
| TEMP_CAST="/tmp/asciinema_auto_$ASCIINEMA_OUTER_PID.cast" | |
| INTENT_FILE="/tmp/asciinema_intent_$ASCIINEMA_OUTER_PID" | |
| rm -f "$INTENT_FILE" | |
| # 5. Start recording (This blocks until the inner shell is closed) | |
| asciinema rec -q "$TEMP_CAST" | |
| # 6. Post-recording wrap-up | |
| KEEP_OPEN=0 | |
| if [ -f "$TEMP_CAST" ]; then | |
| FINAL_NAME="$DEFAULT_FILENAME" | |
| FINAL_DEST="auto" # Default if no explicit save command is issued | |
| if [ -f "$INTENT_FILE" ]; then | |
| IFS='|' read -r FINAL_NAME FINAL_DEST FLAG < "$INTENT_FILE" | |
| rm -f "$INTENT_FILE" | |
| [ "$FLAG" = "KEEP_OPEN" ] && KEEP_OPEN=1 | |
| fi | |
| # Ensure the filename ends in .cast | |
| [[ "$FINAL_NAME" != *.cast ]] && FINAL_NAME="${FINAL_NAME}.cast" | |
| if [ "$FINAL_DEST" = "upload" ]; then | |
| echo "Uploading session $FINAL_NAME..." | |
| if asciinema upload "$TEMP_CAST"; then | |
| rm -f "$TEMP_CAST" | |
| else | |
| echo "Upload failed (network issue?). Moving to pending queue." | |
| mv "$TEMP_CAST" "$PENDING_DIR/$FINAL_NAME" | |
| fi | |
| elif [ "$FINAL_DEST" = "local" ]; then | |
| mv "$TEMP_CAST" "$RECORD_DIR/$FINAL_NAME" | |
| echo "Session saved locally to $RECORD_DIR/$FINAL_NAME" | |
| else | |
| # Handles "auto" fallback when terminal is closed normally | |
| mv "$TEMP_CAST" "$AUTO_SAVE_DIR/$FINAL_NAME" | |
| echo "Session auto-saved to $AUTO_SAVE_DIR/$FINAL_NAME" | |
| fi | |
| fi | |
| # 7. Smart Exit Logic | |
| if [ "$KEEP_OPEN" -eq 1 ]; then | |
| echo -e "\n\033[1;33m[!] Recording stopped. You are now in a standard, unrecorded session.\033[0m" | |
| exit 3 | |
| else | |
| exit 0 | |
| fi | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment