It's too big to VM test, filled the whole virtual disk, so I am trying another option:
0-LastOS-Manage-Repo.sh
Code:
#!/bin/bash
# 1. WINDOW SPAWNING LOGIC
if ! [ -t 0 ]; then
gnome-terminal -- bash "$0" "$@"
exit
fi
# 2. ROOT ELEVATION
if [ "$EUID" -ne 0 ]; then
echo "This script requires administrative privileges."
if ! sudo -v; then
echo "Authentication failed. Press Enter to exit."
read
exit 1
fi
exec sudo "$0" "$@"
fi
# 3. PATH DETECTION
USB_PATH=$(dirname "$(readlink -f "$0")")
CONF_FILE="/etc/apt/apt.conf.d/99persist-to-usb"
LOCAL_CACHE="/var/cache/apt/archives"
# FIX: Detect the real user's home even when running as sudo
if [ -n "$SUDO_USER" ]; then
REAL_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6)
else
REAL_HOME=$HOME
fi
header() {
clear
FREE_SPACE=$(df -h "$USB_PATH" 2>/dev/null | awk 'NR==2 {print $4}')
echo "==============================================="
echo " 0-LastOS REPOSITORY MANAGER (exFAT) "
echo "==============================================="
echo " USB Location: $USB_PATH"
echo " USB Free: $FREE_SPACE"
if [ -f "$CONF_FILE" ]; then
echo " STATUS: CAPTURE MODE ACTIVE (USB Cache)"
else
echo " STATUS: STANDARD MODE (System Cache)"
fi
echo "-----------------------------------------------"
}
create_failsafe() {
echo "Creating Emergency Fail-Safe autostart..."
# Use REAL_HOME to target the user's directory, not /root
mkdir -p "$REAL_HOME/.config/autostart" "$REAL_HOME/.local/bin"
local FAILSAFE_SCRIPT="$REAL_HOME/.local/bin/lastos-failsafe.sh"
local AUTOSTART_FILE="$REAL_HOME/.config/autostart/lastos-failsafe.desktop"
cat <<EOF > "$FAILSAFE_SCRIPT"
#!/bin/bash
# Universal check: Wait until the graphical session is ready
until [ -n "\$DISPLAY" ] && [ -n "\$XAUTHORITY" ]; do
sleep 1
done
# Give the Auth Agent a moment to initialize
sleep 2
# Run the cleanup
if pkexec sh -c "rm -f $CONF_FILE && find $LOCAL_CACHE -type l -delete"; then
rm -f "$AUTOSTART_FILE"
rm -f "$FAILSAFE_SCRIPT"
fi
EOF
chmod +x "$FAILSAFE_SCRIPT"
cat <<EOF > "$AUTOSTART_FILE"
[Desktop Entry]
Type=Application
Name=LastOS Fail-Safe
Exec=$FAILSAFE_SCRIPT
Terminal=false
NoDisplay=true
X-GNOME-Autostart-enabled=true
EOF
# Ensure the user owns these files so the Desktop Environment can execute them
if [ -n "$SUDO_USER" ]; then
chown "$SUDO_USER:$SUDO_USER" "$FAILSAFE_SCRIPT" "$AUTOSTART_FILE"
fi
}
do_capture() {
create_failsafe
echo "Preparing USB for capture..."
mkdir -p "$USB_PATH/partial"
echo "Redirecting APT downloads to USB..."
{
echo "Dir::Cache::Archives \"$USB_PATH/\";"
echo "Binary::apt::APT::Keep-Downloaded-Packages \"true\";"
echo "APT::Keep-Downloaded-Packages \"true\";"
echo "APT::Sandbox::User \"root\";"
} > $CONF_FILE
echo "Refreshing package lists..."
apt update
echo "Done. All downloads will stay on this USB."
}
do_link() {
create_failsafe
echo "Linking .deb files from USB to system cache..."
ln -s "$USB_PATH"/*.deb "$LOCAL_CACHE/" 2>/dev/null
echo "Refreshing package lists..."
apt update
echo "Links created. System will now use USB files."
}
do_prune() {
echo "Scanning for old package versions on USB..."
cd "$USB_PATH" || return
ls *.deb 2>/dev/null | cut -d'_' -f1 | sort -u | while read -r pkg; do
count=$(ls ${pkg}_*.deb 2>/dev/null | wc -l)
if [ "$count" -gt 1 ]; then
echo "Found $count versions of $pkg..."
old_files=$(ls ${pkg}_*.deb | sort -V | head -n -1)
for file in $old_files; do
echo " Deleting older version: $file"
rm "$file"
done
fi
done
echo "Pruning complete."
}
do_unlink() {
echo "Unlinking and cleaning up system settings..."
# 1. Remove APT Redirect and Boot Failsafes using REAL_HOME
[ -f "$CONF_FILE" ] && rm -f "$CONF_FILE"
rm -f "$REAL_HOME/.local/bin/lastos-failsafe.sh"
rm -f "$REAL_HOME/.config/autostart/lastos-failsafe.desktop"
# 2. Clean System Cache
echo "Removing symlinks from $LOCAL_CACHE..."
find "$LOCAL_CACHE" -type l -delete
# 3. Clean USB Files
echo "Cleaning USB (Wiping partials & locks)..."
rm -rf "$USB_PATH/partial"
rm -f "$USB_PATH/lock"
# 4. Permissions Fix
echo "Resetting USB folder permissions..."
chmod -R 777 "$USB_PATH" 2>/dev/null
echo "System unlinked and USB cleaned."
}
# 4. ARGUMENT HANDLING
if [ -n "$1" ]; then
case $1 in
-capture) do_capture ;;
-link) do_link ;;
-prune) do_prune ;;
-unlink) do_unlink ;;
*) echo "Usage: $0 {-capture|-link|-prune|-unlink}" ;;
esac
exit 0
fi
# 5. INTERACTIVE MENU
while true; do
header
echo " 1) CAPTURE: Save all new downloads to USB"
echo " 2) LINK: Use existing USB files (No download)"
echo " 3) PRUNE: Delete old versions from USB"
echo " 4) UNLINK: Reset system & Wipe USB Temp files"
echo " 5) EXIT"
echo "-----------------------------------------------"
read -p " Select an option [1-5]: " choice
case $choice in
1) do_capture ; echo ""; read -p "Press Enter to return..." ;;
2) do_link ; echo ""; read -p "Press Enter to return..." ;;
3) do_prune ; echo ""; read -p "Press Enter to return..." ;;
4) do_unlink ; echo ""; read -p "Press Enter to return..." ;;
5) exit 0 ;;
*) echo "Invalid choice." ; sleep 1 ;;
esac
done
Usage: GUI double click the .sh file in the folder you want to capture or link to the local repository of the current OS, or from command line arguments:
- Run -capture to turn your USB into a sponge for new .debs.
- Run -link to deploy your library to any new machine/VM without internet usage.
- Run -link-ro this protects the cache from the ap-get clean deleting all your precious .deb files on you
- Run -prune to keep the "one-version-only" cleanliness.
- Run -unlink to reset the system and walk away clean.
And if anything crashes, a
Fail-Safe will be waiting at the next boot to tidy up for you.
I've made it capture all the files I need post install and can include them on my USB drive, go into that folder and double click picking the Link option - this links to all the .deb files to the USB disk, so instead of downloading them, it grabs them off the USB.
I know this all sounds weird, but it works and I am going to build the full thing to give it a proper test

I hate wasting internet usage and time, makes more sense to cache where I can.
-EDIT-
The script captures great, I have done the games, the apps and now I am doing the builder. With any luck It'll mean I no longer have to keep downloading .deb packages again and again, some haven't been updated since before 2020, so why would I keep downloading it when a local cache will suffice?
I tested the link method and it works, but I still want to test with a large cache, I still think it'll be fast and fine though
