From 953c80e2cfff53e519a0640a22f9f32e7c1eabfe Mon Sep 17 00:00:00 2001 From: meek2100 <34908880+meek2100@users.noreply.github.com> Date: Fri, 23 May 2025 11:26:36 -0700 Subject: [PATCH 1/8] Add support to cache IPK packages for offline install --- opkgscript.sh | 104 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 94 insertions(+), 10 deletions(-) diff --git a/opkgscript.sh b/opkgscript.sh index d46bbb0..aa9eaf3 100755 --- a/opkgscript.sh +++ b/opkgscript.sh @@ -11,21 +11,25 @@ # Thanks, too, to hnyman for important comments on this script # # Version history +# 0.2.3 - added support for selective IPK caching with version retention control for offline recovery installs # 0.2.2 - editorial tweaks to help text -richb-hanvover # 0.2.1 - fixed typo in awk script for dependency detection # 0.2.0 - command interface # 0.1.0 - Initial release -PCKGLIST=/etc/config/opkg.installed # default package list -SCRIPTNAME=$(basename $0) # name of this script -COMMAND="" # command to execute +PCKGLIST=/etc/config/opkg.installed # Default package list +IPK_CACHE_LIST="/etc/config/opkg.ipk_cache_list" # List of packages to cache IPKs for +IPK_CACHE_DIR="/etc/opkg/ipk_cache" # Directory to store cached IPK files +IPK_CACHE_ALL_VERSIONS=false # Cache only the latest IPK per package (default). Set to true to keep all versions. +SCRIPTNAME=$(basename $0) # Name of this script +COMMAND="" # Command to execute -INSTLIST=$(mktemp) # list of packages to install -PREQLIST=$(mktemp) # list of prerequisite packages +INSTLIST=$(mktemp) # List of packages to install +PREQLIST=$(mktemp) # List of prerequisite packages -UPDATE=false # update the package database -OPKGOPT="" # options for opkg calls -VERBOSE=false # be verbose +UPDATE=false # Update the package database +OPKGOPT="" # Options for opkg calls +VERBOSE=false # Be verbose cleanup () { rm -f $INSTLIST $PREQLIST @@ -40,12 +44,18 @@ Available commands: write write a list of currently installed packages install install packages on list not currently installed script output a script to install missing packages + cache-ipks download .ipk files for specific packages to a local cache Options: -u update the package database -t test only, execute opkg commands with --noaction -v be verbose +Configuration: + IPK_CACHE_ALL_VERSIONS in script controls whether to cache all .ipk versions or just the latest. + Default is to cache only the latest. Set IPK_CACHE_ALL_VERSIONS=true to retain all versions. + Warning: caching all versions may consume significant storage and must be cleaned manually. + $SCRIPTNAME can be used to re-install those packages that were installed before a firmware upgrade but are not part of the new firmware image. @@ -70,7 +80,7 @@ Alternatively, you can execute to output a shell script that will contain calls to opkg to install those missing packages. This might be useful if you want to check which packages -would be installed of if you want to edit that list. +would be installed or if you want to edit that list. In order for this script to work after a firmware upgrade or reboot, the opkg database must have been updated. You can use the option -u to do this. @@ -84,7 +94,7 @@ the call to opkg to write the list of installed packages, though. trap cleanup SIGHUP SIGINT SIGTERM EXIT # parse command line options -while getopts "htuvw" OPTS; do +while getopts "htuv" OPTS; do case $OPTS in t ) OPKGOPT="$OPKGOPT --noaction";; @@ -99,6 +109,8 @@ while getopts "htuvw" OPTS; do done shift $(($OPTIND - 1)) +[ "$VERBOSE" = true ] && set -x + # Set the command COMMAND=$1 @@ -135,6 +147,78 @@ if [ $COMMAND = "write" ] ; then exit 0 fi +# +# Cache IPKs +# + +if [ $COMMAND = "cache-ipks" ] ; then + if [ ! -f "$IPK_CACHE_LIST" ]; then + echo "Error: IPK cache list '$IPK_CACHE_LIST' not found." + echo "Please create this file and list the packages you want to cache (one per line)." + exit 1 + fi + + if [ ! -d "$IPK_CACHE_DIR" ]; then + if $VERBOSE; then + echo "Creating IPK cache directory: $IPK_CACHE_DIR" + fi + mkdir -p "$IPK_CACHE_DIR" || { + echo "Error: Could not create IPK cache directory '$IPK_CACHE_DIR'." + exit 1 + } + fi + + if $VERBOSE; then + echo "Caching IPK files from list: $IPK_CACHE_LIST to $IPK_CACHE_DIR" + echo "Running opkg update..." + fi + + opkg update + + if $VERBOSE; then + echo "Finished opkg update" + fi + + cat "$IPK_CACHE_LIST" | while read PACKAGE; do + PACKAGE=$(echo "$PACKAGE" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -z "$PACKAGE" ] && continue + + IPK_LATEST_FILENAME=$(opkg info "$PACKAGE" | grep "^Filename:" | awk '{print $2}') + [ -z "$IPK_LATEST_FILENAME" ] && { + echo "Warning: Could not find filename for package '$PACKAGE'. Skipping." + continue + } + + BASE_PACKAGE_NAME=$(opkg info "$PACKAGE" | grep "^Package:" | awk '{print $2}') + IPK_LATEST_PATH="$IPK_CACHE_DIR/$IPK_LATEST_FILENAME" + + if ! $IPK_CACHE_ALL_VERSIONS && [ -n "$BASE_PACKAGE_NAME" ]; then + CACHED_FILES=$(find "$IPK_CACHE_DIR" -maxdepth 1 -type f -name "${BASE_PACKAGE_NAME}_*.ipk") + for CACHED_FILE in $CACHED_FILES; do + CACHED_FILENAME=$(basename "$CACHED_FILE") + if [ "$CACHED_FILENAME" != "$IPK_LATEST_FILENAME" ]; then + $VERBOSE && echo "Removing old version of $BASE_PACKAGE_NAME: $CACHED_FILE" + rm -f "$CACHED_FILE" || echo "Warning: Failed to remove $CACHED_FILE" + fi + done + fi + + if [ -f "$IPK_LATEST_PATH" ]; then + $VERBOSE && echo "Package '$PACKAGE' IPK already exists: $IPK_LATEST_FILENAME (skipping download)" + else + $VERBOSE && echo "Downloading '$PACKAGE' (latest version: $IPK_LATEST_FILENAME)" + opkg $OPKGOPT download "$PACKAGE" + if [ $? -eq 0 ] && [ -f "./$IPK_LATEST_FILENAME" ]; then + mv "./$IPK_LATEST_FILENAME" "$IPK_LATEST_PATH" || echo "Error: Failed to move downloaded IPK" + $VERBOSE && echo "Successfully moved to $IPK_CACHE_DIR" + else + echo "Warning: Download failed or file missing for '$PACKAGE'" + fi + fi + done + exit 0 +fi + # # Update # From f0cb22206c0f8c3fc979c83086ac55676687a7cf Mon Sep 17 00:00:00 2001 From: meek2100 <34908880+meek2100@users.noreply.github.com> Date: Fri, 23 May 2025 11:56:08 -0700 Subject: [PATCH 2/8] Improve logic around caching IPK so don't run opkg update multiple times. --- opkgscript.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/opkgscript.sh b/opkgscript.sh index aa9eaf3..44056d8 100755 --- a/opkgscript.sh +++ b/opkgscript.sh @@ -173,7 +173,21 @@ if [ $COMMAND = "cache-ipks" ] ; then echo "Running opkg update..." fi - opkg update + # Only update if lists are older than 5 minutes + CACHE_AGE_LIMIT=300 # seconds + needs_update=false + for list in /var/opkg-lists/*; do + if [ ! -f "$list" ] || [ "$(($(date +%s) - $(stat -c %Y "$list")))" -gt "$CACHE_AGE_LIMIT" ]; then + needs_update=true + break + fi + done + + if $needs_update; then + opkg update + else + echo "Skipping opkg update: cache is fresh" + fi if $VERBOSE; then echo "Finished opkg update" From b388f2214a6b4913a659a957cb7a35c7a575c4e5 Mon Sep 17 00:00:00 2001 From: meek2100 <34908880+meek2100@users.noreply.github.com> Date: Fri, 23 May 2025 12:00:05 -0700 Subject: [PATCH 3/8] Move [ "$VERBOSE" = true ] && set -x to be managed by debug trace instead. --- opkgscript.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/opkgscript.sh b/opkgscript.sh index 44056d8..c5844a9 100755 --- a/opkgscript.sh +++ b/opkgscript.sh @@ -30,6 +30,8 @@ PREQLIST=$(mktemp) # List of prerequisite packa UPDATE=false # Update the package database OPKGOPT="" # Options for opkg calls VERBOSE=false # Be verbose +DEBUG_TRACE=false # Set to true to enable shell debug tracing (set -x) + cleanup () { rm -f $INSTLIST $PREQLIST @@ -109,7 +111,7 @@ while getopts "htuv" OPTS; do done shift $(($OPTIND - 1)) -[ "$VERBOSE" = true ] && set -x +[ "$DEBUG_TRACE" = true ] && set -x # Set the command COMMAND=$1 From f4164e65df295abe2644b69798541ca955fa20c6 Mon Sep 17 00:00:00 2001 From: meek2100 <34908880+meek2100@users.noreply.github.com> Date: Fri, 23 May 2025 12:06:52 -0700 Subject: [PATCH 4/8] Improve logging with debug trace option. --- opkgscript.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/opkgscript.sh b/opkgscript.sh index c5844a9..71612e1 100755 --- a/opkgscript.sh +++ b/opkgscript.sh @@ -52,6 +52,7 @@ Options: -u update the package database -t test only, execute opkg commands with --noaction -v be verbose + -x enable shell debug tracing (set -x) Configuration: IPK_CACHE_ALL_VERSIONS in script controls whether to cache all .ipk versions or just the latest. @@ -96,7 +97,7 @@ the call to opkg to write the list of installed packages, though. trap cleanup SIGHUP SIGINT SIGTERM EXIT # parse command line options -while getopts "htuv" OPTS; do +while getopts "htuvx" OPTS; do case $OPTS in t ) OPKGOPT="$OPKGOPT --noaction";; @@ -104,6 +105,8 @@ while getopts "htuv" OPTS; do UPDATE=true;; v ) VERBOSE=true;; + x ) + DEBUG_TRACE=true; VERBOSE=true;; [h\?*] ) echo_usage exit 0;; From ee6ebbf226b1ead8126da4206471aca11232443b Mon Sep 17 00:00:00 2001 From: meek2100 <34908880+meek2100@users.noreply.github.com> Date: Fri, 23 May 2025 13:32:52 -0700 Subject: [PATCH 5/8] Better IPK Stats --- opkgscript.sh | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/opkgscript.sh b/opkgscript.sh index 71612e1..824a3fe 100755 --- a/opkgscript.sh +++ b/opkgscript.sh @@ -198,9 +198,15 @@ if [ $COMMAND = "cache-ipks" ] ; then echo "Finished opkg update" fi + TOTAL_LISTED=0 + TOTAL_DOWNLOADED=0 + TOTAL_UP_TO_DATE=0 + TOTAL_REMOVED=0 + cat "$IPK_CACHE_LIST" | while read PACKAGE; do PACKAGE=$(echo "$PACKAGE" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') [ -z "$PACKAGE" ] && continue + TOTAL_LISTED=$((TOTAL_LISTED + 1)) IPK_LATEST_FILENAME=$(opkg info "$PACKAGE" | grep "^Filename:" | awk '{print $2}') [ -z "$IPK_LATEST_FILENAME" ] && { @@ -216,25 +222,34 @@ if [ $COMMAND = "cache-ipks" ] ; then for CACHED_FILE in $CACHED_FILES; do CACHED_FILENAME=$(basename "$CACHED_FILE") if [ "$CACHED_FILENAME" != "$IPK_LATEST_FILENAME" ]; then - $VERBOSE && echo "Removing old version of $BASE_PACKAGE_NAME: $CACHED_FILE" - rm -f "$CACHED_FILE" || echo "Warning: Failed to remove $CACHED_FILE" + $VERBOSE && echo "Removing older version of $BASE_PACKAGE_NAME: $CACHED_FILE" + rm -f "$CACHED_FILE" && TOTAL_REMOVED=$((TOTAL_REMOVED + 1)) fi done fi if [ -f "$IPK_LATEST_PATH" ]; then - $VERBOSE && echo "Package '$PACKAGE' IPK already exists: $IPK_LATEST_FILENAME (skipping download)" + echo "$PACKAGE is up to date ($IPK_LATEST_FILENAME)" + TOTAL_UP_TO_DATE=$((TOTAL_UP_TO_DATE + 1)) else - $VERBOSE && echo "Downloading '$PACKAGE' (latest version: $IPK_LATEST_FILENAME)" + echo "Downloading latest version of $PACKAGE ($IPK_LATEST_FILENAME)" opkg $OPKGOPT download "$PACKAGE" if [ $? -eq 0 ] && [ -f "./$IPK_LATEST_FILENAME" ]; then - mv "./$IPK_LATEST_FILENAME" "$IPK_LATEST_PATH" || echo "Error: Failed to move downloaded IPK" - $VERBOSE && echo "Successfully moved to $IPK_CACHE_DIR" + mv "./$IPK_LATEST_FILENAME" "$IPK_LATEST_PATH" + TOTAL_DOWNLOADED=$((TOTAL_DOWNLOADED + 1)) + $VERBOSE && echo "Saved to $IPK_CACHE_DIR" else echo "Warning: Download failed or file missing for '$PACKAGE'" fi fi done + + echo "" + echo "IPK Cache Summary:" + printf " Packages scanned: %d\n" "$TOTAL_LISTED" + printf " New downloads: %d\n" "$TOTAL_DOWNLOADED" + printf " Older versions removed: %d\n" "$TOTAL_REMOVED" + printf " Already up to date: %d\n" "$TOTAL_UP_TO_DATE" exit 0 fi From bd42ef10b12828343c0588514b143b3e452089c9 Mon Sep 17 00:00:00 2001 From: meek2100 <34908880+meek2100@users.noreply.github.com> Date: Fri, 23 May 2025 14:14:07 -0700 Subject: [PATCH 6/8] Improving logic for IPK caching and optimize the verbose logic --- opkgscript.sh | 200 ++++++++++++++++++++++++++++---------------------- 1 file changed, 111 insertions(+), 89 deletions(-) diff --git a/opkgscript.sh b/opkgscript.sh index 824a3fe..d9da16a 100755 --- a/opkgscript.sh +++ b/opkgscript.sh @@ -47,7 +47,7 @@ Available commands: install install packages on list not currently installed script output a script to install missing packages cache-ipks download .ipk files for specific packages to a local cache - + Options: -u update the package database -t test only, execute opkg commands with --noaction @@ -90,7 +90,7 @@ opkg database must have been updated. You can use the option -u to do this. You can specify the option -t to test what $SCRIPTNAME would do. All calls to opkg will be made with the option --noaction. This does not influence -the call to opkg to write the list of installed packages, though. +the call to opkg to write the list of installed packages, though. " } @@ -99,17 +99,17 @@ trap cleanup SIGHUP SIGINT SIGTERM EXIT # parse command line options while getopts "htuvx" OPTS; do case $OPTS in - t ) - OPKGOPT="$OPKGOPT --noaction";; - u ) - UPDATE=true;; - v ) - VERBOSE=true;; - x ) - DEBUG_TRACE=true; VERBOSE=true;; - [h\?*] ) - echo_usage - exit 0;; + + t ) OPKGOPT="$OPKGOPT --noaction";; + + u ) UPDATE=true;; + + v ) VERBOSE=true;; + + x ) DEBUG_TRACE=true; VERBOSE=true;; + + [h\?*] ) echo_usage; exit 0;; + esac done shift $(($OPTIND - 1)) @@ -143,10 +143,10 @@ fi # Write # -if [ $COMMAND = "write" ] ; then - if $VERBOSE; then - echo "Saving package list to $PCKGLIST" - fi +if [ $COMMAND = "write" ]; then + + $VERBOSE && echo "Saving package list to $PCKGLIST" + # NOTE: option --noaction not valid for list-installed opkg list-installed > "$PCKGLIST" exit 0 @@ -156,7 +156,7 @@ fi # Cache IPKs # -if [ $COMMAND = "cache-ipks" ] ; then +if [ $COMMAND = "cache-ipks" ]; then if [ ! -f "$IPK_CACHE_LIST" ]; then echo "Error: IPK cache list '$IPK_CACHE_LIST' not found." echo "Please create this file and list the packages you want to cache (one per line)." @@ -164,92 +164,114 @@ if [ $COMMAND = "cache-ipks" ] ; then fi if [ ! -d "$IPK_CACHE_DIR" ]; then - if $VERBOSE; then - echo "Creating IPK cache directory: $IPK_CACHE_DIR" - fi + + $VERBOSE && echo "Creating IPK cache directory: $IPK_CACHE_DIR" + mkdir -p "$IPK_CACHE_DIR" || { echo "Error: Could not create IPK cache directory '$IPK_CACHE_DIR'." exit 1 } fi - if $VERBOSE; then - echo "Caching IPK files from list: $IPK_CACHE_LIST to $IPK_CACHE_DIR" - echo "Running opkg update..." - fi + + $VERBOSE && echo "Caching IPK files from list: $IPK_CACHE_LIST to $IPK_CACHE_DIR" + $VERBOSE && echo "Checking freshness of opkg cache..." + # Only update if lists are older than 5 minutes CACHE_AGE_LIMIT=300 # seconds needs_update=false for list in /var/opkg-lists/*; do - if [ ! -f "$list" ] || [ "$(($(date +%s) - $(stat -c %Y "$list")))" -gt "$CACHE_AGE_LIMIT" ]; then + if [ ! -f "$list" ] || [ "$(($(date +%s) - $(date -r "$list" +%s)))" -gt "$CACHE_AGE_LIMIT" ]; then needs_update=true break fi done if $needs_update; then + $VERBOSE && echo "Running opkg update..." opkg update + $VERBOSE && echo "Finished opkg update" else echo "Skipping opkg update: cache is fresh" fi - if $VERBOSE; then - echo "Finished opkg update" - fi - - TOTAL_LISTED=0 - TOTAL_DOWNLOADED=0 - TOTAL_UP_TO_DATE=0 - TOTAL_REMOVED=0 - - cat "$IPK_CACHE_LIST" | while read PACKAGE; do - PACKAGE=$(echo "$PACKAGE" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') - [ -z "$PACKAGE" ] && continue - TOTAL_LISTED=$((TOTAL_LISTED + 1)) - - IPK_LATEST_FILENAME=$(opkg info "$PACKAGE" | grep "^Filename:" | awk '{print $2}') - [ -z "$IPK_LATEST_FILENAME" ] && { - echo "Warning: Could not find filename for package '$PACKAGE'. Skipping." - continue - } - - BASE_PACKAGE_NAME=$(opkg info "$PACKAGE" | grep "^Package:" | awk '{print $2}') - IPK_LATEST_PATH="$IPK_CACHE_DIR/$IPK_LATEST_FILENAME" - - if ! $IPK_CACHE_ALL_VERSIONS && [ -n "$BASE_PACKAGE_NAME" ]; then - CACHED_FILES=$(find "$IPK_CACHE_DIR" -maxdepth 1 -type f -name "${BASE_PACKAGE_NAME}_*.ipk") - for CACHED_FILE in $CACHED_FILES; do - CACHED_FILENAME=$(basename "$CACHED_FILE") - if [ "$CACHED_FILENAME" != "$IPK_LATEST_FILENAME" ]; then - $VERBOSE && echo "Removing older version of $BASE_PACKAGE_NAME: $CACHED_FILE" - rm -f "$CACHED_FILE" && TOTAL_REMOVED=$((TOTAL_REMOVED + 1)) - fi - done - fi - - if [ -f "$IPK_LATEST_PATH" ]; then - echo "$PACKAGE is up to date ($IPK_LATEST_FILENAME)" - TOTAL_UP_TO_DATE=$((TOTAL_UP_TO_DATE + 1)) - else - echo "Downloading latest version of $PACKAGE ($IPK_LATEST_FILENAME)" - opkg $OPKGOPT download "$PACKAGE" - if [ $? -eq 0 ] && [ -f "./$IPK_LATEST_FILENAME" ]; then - mv "./$IPK_LATEST_FILENAME" "$IPK_LATEST_PATH" - TOTAL_DOWNLOADED=$((TOTAL_DOWNLOADED + 1)) - $VERBOSE && echo "Saved to $IPK_CACHE_DIR" - else - echo "Warning: Download failed or file missing for '$PACKAGE'" - fi - fi - done + TOTAL=0 + DOWNLOADED=0 + SKIPPED=0 + REMOVED=0 + + while read PACKAGE; do + PACKAGE=$(echo "$PACKAGE" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -z "$PACKAGE" ] && continue + TOTAL=$((TOTAL + 1)) + + IPK_LATEST_FILENAME=$(opkg info "$PACKAGE" | grep "^Filename:" | awk '{print $2}') + + [ -z "$IPK_LATEST_FILENAME" ] && { + echo "Warning: Could not find filename for package '$PACKAGE'. Skipping." + continue + } + + BASE_PACKAGE_NAME=$(opkg info "$PACKAGE" | grep "^Package:" | awk '{print $2}') + IPK_LATEST_PATH="$IPK_CACHE_DIR/$IPK_LATEST_FILENAME" + + + + + if ! $IPK_CACHE_ALL_VERSIONS && [ -n "$BASE_PACKAGE_NAME" ]; then + CACHED_FILES=$(find "$IPK_CACHE_DIR" -maxdepth 1 -type f -name "${BASE_PACKAGE_NAME}_*.ipk") + for CACHED_FILE in $CACHED_FILES; do + CACHED_FILENAME=$(basename "$CACHED_FILE") + if [ "$CACHED_FILENAME" != "$IPK_LATEST_FILENAME" ]; then + $VERBOSE && echo "Removing old version of $BASE_PACKAGE_NAME: $CACHED_FILENAME" + rm -f "$CACHED_FILE" || echo "Warning: Failed to remove $CACHED_FILE" + REMOVED=$((REMOVED + 1)) + fi + done + fi + + if [ -f "$IPK_LATEST_PATH" ]; then + echo "$PACKAGE is up to date ($IPK_LATEST_FILENAME)" + SKIPPED=$((SKIPPED + 1)) + else + $VERBOSE && echo "Downloading $PACKAGE → $IPK_LATEST_FILENAME" + opkg $OPKGOPT download "$PACKAGE" + if [ $? -eq 0 ] && [ -f "./$IPK_LATEST_FILENAME" ]; then + mv "./$IPK_LATEST_FILENAME" "$IPK_LATEST_PATH" || echo "Error: Failed to move downloaded IPK" + $VERBOSE && echo "Moved to $IPK_CACHE_DIR" + DOWNLOADED=$((DOWNLOADED + 1)) + else + echo "Warning: Download failed or file missing for '$PACKAGE'" + fi + + fi + done < "$IPK_CACHE_LIST" + + + + + + + + + + + + + + + + echo "" echo "IPK Cache Summary:" - printf " Packages scanned: %d\n" "$TOTAL_LISTED" - printf " New downloads: %d\n" "$TOTAL_DOWNLOADED" - printf " Older versions removed: %d\n" "$TOTAL_REMOVED" - printf " Already up to date: %d\n" "$TOTAL_UP_TO_DATE" + printf " %-25s %d\n" "Packages scanned:" $TOTAL + printf " %-25s %d\n" "New downloads:" $DOWNLOADED + printf " %-25s %d\n" "Older versions removed:" $REMOVED + printf " %-25s %d\n" "Already up to date:" $SKIPPED + echo "" + exit 0 fi @@ -267,9 +289,9 @@ fi if [ $COMMAND == "install" ] || [ $COMMAND == "script" ]; then # detect uninstalled packages - if $VERBOSE && [ $COMMAND != "script" ]; then - echo "Checking packages... " - fi + $VERBOSE && [ $COMMAND != "script" ] && echo "Checking packages... " + + cat "$PCKGLIST" | while read PACKAGE SEP VERSION; do # opkg status is much faster than opkg info # it only returns status of installed packages @@ -280,10 +302,10 @@ if [ $COMMAND == "install" ] || [ $COMMAND == "script" ]; then # collect prerequisites opkg info "$PACKAGE" | awk "/^Depends: / { - sub(\"Depends: \", \"\"); \ - gsub(\", \", \"\\n\"); \ - print >> \"$PREQLIST\"; \ - }" + sub(\"Depends: \", \"\"); + gsub(\", \", \"\\n\"); + print >> \"$PREQLIST\"; + }" fi done fi @@ -297,9 +319,9 @@ if [ $COMMAND == "install" ]; then cat "$INSTLIST" | while read PACKAGE; do if grep -q "^$PACKAGE\$" "$PREQLIST"; then # prerequisite package, will be installed automatically - if $VERBOSE; then - echo "$PACKAGE installed automatically" - fi + + $VERBOSE && echo "$PACKAGE installed automatically" + else # install package opkg $OPKGOPT install $PACKAGE From a392f087b486a103ded0965bb5c4bcf21b017a34 Mon Sep 17 00:00:00 2001 From: meek2100 <34908880+meek2100@users.noreply.github.com> Date: Fri, 23 May 2025 14:23:49 -0700 Subject: [PATCH 7/8] Clean up more spacing --- opkgscript.sh | 43 ------------------------------------------- 1 file changed, 43 deletions(-) diff --git a/opkgscript.sh b/opkgscript.sh index d9da16a..11fddb4 100755 --- a/opkgscript.sh +++ b/opkgscript.sh @@ -99,17 +99,11 @@ trap cleanup SIGHUP SIGINT SIGTERM EXIT # parse command line options while getopts "htuvx" OPTS; do case $OPTS in - t ) OPKGOPT="$OPKGOPT --noaction";; - u ) UPDATE=true;; - v ) VERBOSE=true;; - x ) DEBUG_TRACE=true; VERBOSE=true;; - [h\?*] ) echo_usage; exit 0;; - esac done shift $(($OPTIND - 1)) @@ -127,7 +121,6 @@ fi # # Help # - if [ "x$COMMAND" == "x" ]; then echo "No command specified." echo "" @@ -142,11 +135,8 @@ fi # # Write # - if [ $COMMAND = "write" ]; then - $VERBOSE && echo "Saving package list to $PCKGLIST" - # NOTE: option --noaction not valid for list-installed opkg list-installed > "$PCKGLIST" exit 0 @@ -155,7 +145,6 @@ fi # # Cache IPKs # - if [ $COMMAND = "cache-ipks" ]; then if [ ! -f "$IPK_CACHE_LIST" ]; then echo "Error: IPK cache list '$IPK_CACHE_LIST' not found." @@ -164,19 +153,15 @@ if [ $COMMAND = "cache-ipks" ]; then fi if [ ! -d "$IPK_CACHE_DIR" ]; then - $VERBOSE && echo "Creating IPK cache directory: $IPK_CACHE_DIR" - mkdir -p "$IPK_CACHE_DIR" || { echo "Error: Could not create IPK cache directory '$IPK_CACHE_DIR'." exit 1 } fi - $VERBOSE && echo "Caching IPK files from list: $IPK_CACHE_LIST to $IPK_CACHE_DIR" $VERBOSE && echo "Checking freshness of opkg cache..." - # Only update if lists are older than 5 minutes CACHE_AGE_LIMIT=300 # seconds @@ -207,7 +192,6 @@ if [ $COMMAND = "cache-ipks" ]; then TOTAL=$((TOTAL + 1)) IPK_LATEST_FILENAME=$(opkg info "$PACKAGE" | grep "^Filename:" | awk '{print $2}') - [ -z "$IPK_LATEST_FILENAME" ] && { echo "Warning: Could not find filename for package '$PACKAGE'. Skipping." continue @@ -215,9 +199,6 @@ if [ $COMMAND = "cache-ipks" ]; then BASE_PACKAGE_NAME=$(opkg info "$PACKAGE" | grep "^Package:" | awk '{print $2}') IPK_LATEST_PATH="$IPK_CACHE_DIR/$IPK_LATEST_FILENAME" - - - if ! $IPK_CACHE_ALL_VERSIONS && [ -n "$BASE_PACKAGE_NAME" ]; then CACHED_FILES=$(find "$IPK_CACHE_DIR" -maxdepth 1 -type f -name "${BASE_PACKAGE_NAME}_*.ipk") @@ -244,26 +225,9 @@ if [ $COMMAND = "cache-ipks" ]; then else echo "Warning: Download failed or file missing for '$PACKAGE'" fi - fi done < "$IPK_CACHE_LIST" - - - - - - - - - - - - - - - - echo "" echo "IPK Cache Summary:" printf " %-25s %d\n" "Packages scanned:" $TOTAL @@ -278,7 +242,6 @@ fi # # Update # - if $UPDATE; then opkg $OPKGOPT update fi @@ -286,12 +249,9 @@ fi # # Check # - if [ $COMMAND == "install" ] || [ $COMMAND == "script" ]; then # detect uninstalled packages $VERBOSE && [ $COMMAND != "script" ] && echo "Checking packages... " - - cat "$PCKGLIST" | while read PACKAGE SEP VERSION; do # opkg status is much faster than opkg info # it only returns status of installed packages @@ -313,15 +273,12 @@ fi # # Install or script # - if [ $COMMAND == "install" ]; then # install packages cat "$INSTLIST" | while read PACKAGE; do if grep -q "^$PACKAGE\$" "$PREQLIST"; then # prerequisite package, will be installed automatically - $VERBOSE && echo "$PACKAGE installed automatically" - else # install package opkg $OPKGOPT install $PACKAGE From 20dc9a23b80ce4c435819be34dcbf305ebc1dede Mon Sep 17 00:00:00 2001 From: meek2100 <34908880+meek2100@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:44:52 -0800 Subject: [PATCH 8/8] Rename Why a Spare Router.md since "?" is an invalid character for a Windows path. --- Why a Spare Router?.md => Why a Spare Router.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Why a Spare Router?.md => Why a Spare Router.md (100%) diff --git a/Why a Spare Router?.md b/Why a Spare Router.md similarity index 100% rename from Why a Spare Router?.md rename to Why a Spare Router.md