From 7a2890e934eebb60c906ac98b63fb16f78a610e7 Mon Sep 17 00:00:00 2001 From: "Martinski@GitHub" <119833648+Martinski4GitHub@users.noreply.github.com> Date: Sun, 7 Jul 2024 04:14:20 -0700 Subject: [PATCH 01/14] Set the repo branch variable to "master" for production release --- MerlinAU.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index 3516996a..ea2d2fbb 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -4,7 +4,7 @@ # # Original Creation Date: 2023-Oct-01 by @ExtremeFiretop. # Official Co-Author: @Martinski W. - Date: 2023-Nov-01 -# Last Modified: 2024-Jul-03 +# Last Modified: 2024-Jul-07 ################################################################### set -u @@ -17,7 +17,7 @@ readonly SCRIPT_NAME="MerlinAU" # Script URL Info # ## Set to "master" for Production Releases ## -SCRIPT_BRANCH="dev" +SCRIPT_BRANCH="master" readonly SCRIPT_URL_BASE="https://raw.githubusercontent.com/ExtremeFiretop/MerlinAutoUpdate-Router" SCRIPT_URL_REPO="${SCRIPT_URL_BASE}/$SCRIPT_BRANCH" From a9baf23faa6cb020051ba54e52c38e330ea24bcf Mon Sep 17 00:00:00 2001 From: Martinski <119833648+Martinski4GitHub@users.noreply.github.com> Date: Tue, 9 Jul 2024 02:19:04 -0700 Subject: [PATCH 02/14] Update MerlinAU.sh Sync with current source Master branch. --- MerlinAU.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index ea2d2fbb..07c39afd 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -4,7 +4,7 @@ # # Original Creation Date: 2023-Oct-01 by @ExtremeFiretop. # Official Co-Author: @Martinski W. - Date: 2023-Nov-01 -# Last Modified: 2024-Jul-07 +# Last Modified: 2024-Jul-03 ################################################################### set -u From f675c2f69dc587474ec3e7742cbac079e8f6f916 Mon Sep 17 00:00:00 2001 From: "Martinski@GitHub" <119833648+Martinski4GitHub@users.noreply.github.com> Date: Sat, 4 Jan 2025 17:48:23 -0800 Subject: [PATCH 03/14] Update MerlinAU.sh Syncing... --- MerlinAU.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index 475f494c..b323a97d 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -12,7 +12,7 @@ set -u readonly SCRIPT_VERSION=1.3.9 readonly SCRIPT_NAME="MerlinAU" ## Set to "master" for Production Releases ## -SCRIPT_BRANCH="master" +SCRIPT_BRANCH="dev" ##----------------------------------------## ## Modified by Martinski W. [2024-Jul-03] ## From c9b5b163b8998316778da85809c0fab8268be34e Mon Sep 17 00:00:00 2001 From: Martinski <119833648+Martinski4GitHub@users.noreply.github.com> Date: Mon, 6 Jan 2025 23:16:43 -0800 Subject: [PATCH 04/14] Code Improvements Minor code improvements to handle downloading & installing future updates. --- MerlinAU.sh | 18 +++++++++--------- README.md | 4 ++-- version.txt | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index b323a97d..f65591e8 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -4,12 +4,12 @@ # # Original Creation Date: 2023-Oct-01 by @ExtremeFiretop. # Official Co-Author: @Martinski W. - Date: 2023-Nov-01 -# Last Modified: 2025-Jan-01 +# Last Modified: 2025-Jan-06 ################################################################### set -u ## Set version for each Production Release ## -readonly SCRIPT_VERSION=1.3.9 +readonly SCRIPT_VERSION=1.3.10 readonly SCRIPT_NAME="MerlinAU" ## Set to "master" for Production Releases ## SCRIPT_BRANCH="dev" @@ -1521,9 +1521,9 @@ _CheckForNewGUIVersionUpdate_() return "$retCode" } -##-------------------------------------## -## Added by Martinski W. [2025-Jan-01] ## -##-------------------------------------## +##----------------------------------------## +## Modified by Martinski W. [2025-Jan-06] ## +##----------------------------------------## _CurlFileDownload_() { if [ $# -lt 2 ] || [ -z "$1" ] || [ -z "$2" ] @@ -1532,7 +1532,7 @@ _CurlFileDownload_() curl -LSs --retry 4 --retry-delay 5 --retry-connrefused \ "$1" -o "$tempFilePathDL" - if [ $? -ne 0 ] && [ ! -s "$tempFilePathDL" ] || \ + if [ $? -ne 0 ] || [ ! -s "$tempFilePathDL" ] || \ grep -iq "^404: Not Found" "$tempFilePathDL" then rm -f "$tempFilePathDL" ; retCode=1 else mv -f "$tempFilePathDL" "$2" ; retCode=0 @@ -1541,7 +1541,7 @@ _CurlFileDownload_() } ##----------------------------------------## -## Modified by Martinski W. [2025-Jan-01] ## +## Modified by Martinski W. [2025-Jan-06] ## ##----------------------------------------## _SCRIPTUPDATE_() { @@ -1582,7 +1582,7 @@ _SCRIPTUPDATE_() [ -s "$SCRIPTVERPATH" ] && urlScriptVers="$(cat "$SCRIPTVERPATH")" if [ $# -gt 1 ] && [ "$2" = "newgui" ] && \ _CheckForNewGUIVersionUpdate_ "$theScriptVers" "$urlScriptVers" - then extraParam="forceupdate" ; fi + then extraParam="install" ; fi _ReleaseLock_ exec "$ScriptFilePath" $extraParam exit 0 @@ -1630,7 +1630,7 @@ _SCRIPTUPDATE_() printf "\n$(date) - $SCRIPT_NAME - Successfully downloaded $SCRIPT_NAME v${DLRepoVersion}\n" printf "${CYANct}Update successful! Restarting script...${NOct}\n" sleep 1 - _CheckForNewGUIVersionUpdate_ && extraParam="forceupdate" + _CheckForNewGUIVersionUpdate_ && extraParam="install" _ReleaseLock_ exec "$ScriptFilePath" $extraParam exit 0 diff --git a/README.md b/README.md index 2009f5f8..6d084cc5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MerlinAU - AsusWRT-Merlin Firmware Auto Updater -## v1.3.9 -## 2025-Jan-02 +## v1.3.10 +## 2025-Jan-06 ![image](https://github.com/user-attachments/assets/185f9fe4-acdb-419a-8154-ab6fa6e0fd46) ![image](https://github.com/user-attachments/assets/8f22818d-2118-4c47-a54a-e54fb147fd6b) diff --git a/version.txt b/version.txt index d4c4950a..0c00f610 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.3.9 +1.3.10 From 1a2e378dc253b55e1545441f111211831eec3291 Mon Sep 17 00:00:00 2001 From: Martinski <119833648+Martinski4GitHub@users.noreply.github.com> Date: Fri, 10 Jan 2025 08:36:36 -0800 Subject: [PATCH 05/14] Update MerlinAU.sh Ported fix from the "WebGUI" branch. --- MerlinAU.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index f65591e8..9dfb10c7 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -4,7 +4,7 @@ # # Original Creation Date: 2023-Oct-01 by @ExtremeFiretop. # Official Co-Author: @Martinski W. - Date: 2023-Nov-01 -# Last Modified: 2025-Jan-06 +# Last Modified: 2025-Jan-10 ################################################################### set -u @@ -6002,7 +6002,7 @@ _ManageChangelogGnuton_() } ##----------------------------------------## -## Modified by Martinski W. [2024-Aug-05] ## +## Modified by Martinski W. [2025-Jan-10] ## ##----------------------------------------## _CheckNewUpdateFirmwareNotification_() { @@ -6023,7 +6023,11 @@ _CheckNewUpdateFirmwareNotification_() Update_Custom_Settings FW_New_Update_Notification_Date TBD Update_Custom_Settings FW_New_Update_Notification_Vers TBD Update_Custom_Settings FW_New_Update_Expected_Run_Date TBD - Update_Custom_Settings FW_New_Update_Changelog_Approval TBD + local currentChangelogValue="$(Get_Custom_Setting CheckChangeLog)" + if [ "$currentChangelogValue" = "ENABLED" ] + then + Update_Custom_Settings FW_New_Update_Changelog_Approval TBD + fi return 1 fi From 943d0cbafbff8a5cde232c98eaf27631bd6f4252 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 23:27:55 +0000 Subject: [PATCH 06/14] Bump softprops/action-gh-release in the all-actions group Bumps the all-actions group with 1 update: [softprops/action-gh-release](https://github.com/softprops/action-gh-release). Updates `softprops/action-gh-release` from 2.2.0 to 2.2.1 - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/v2.2.0...v2.2.1) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-patch dependency-group: all-actions ... Signed-off-by: dependabot[bot] --- .github/workflows/Create-NewReleases.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Create-NewReleases.yml b/.github/workflows/Create-NewReleases.yml index 47af0d2b..0c3c4580 100644 --- a/.github/workflows/Create-NewReleases.yml +++ b/.github/workflows/Create-NewReleases.yml @@ -85,7 +85,7 @@ jobs: git push origin ${{ steps.nextver.outputs.tag }} - name: Create Release with Automated Release Notes - uses: softprops/action-gh-release@v2.2.0 + uses: softprops/action-gh-release@v2.2.1 with: token: ${{ secrets.GITHUB_TOKEN }} tag_name: ${{ steps.nextver.outputs.tag }} From b4e3ca26d6625b7915ae3243b5680e804abb9945 Mon Sep 17 00:00:00 2001 From: Martinski <119833648+Martinski4GitHub@users.noreply.github.com> Date: Sat, 15 Feb 2025 21:17:48 -0800 Subject: [PATCH 07/14] Improvements for Updating to WebGUI Version Various code improvements and fine-tuning for updating to newer & latest 1.4.0 WebGUI version. The goal is to allow for a "smooth transition" from previous 1.3.10 to new 1.4.0 version with WebGUI support. The latest changes allow users to update to 1.4.0 using the 1.3.10 CLI menu option to update script or via a direct SSH command. --- MerlinAU.sh | 140 +++++++++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 63 deletions(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index 9dfb10c7..84f5db6f 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -4,7 +4,7 @@ # # Original Creation Date: 2023-Oct-01 by @ExtremeFiretop. # Official Co-Author: @Martinski W. - Date: 2023-Nov-01 -# Last Modified: 2025-Jan-10 +# Last Modified: 2025-Feb-15 ################################################################### set -u @@ -56,18 +56,22 @@ MinSupportedFirmwareVers="3004.386.12.6" routerModelCheckFailed=false offlineUpdateTrigger=false -##--------------------------------------------## -## Modified by ExtremeFiretop [2023-Nov-26] ## -##--------------------------------------------## +##----------------------------------------## +## Modified by Martinski W. [2025-Feb-15] ## +##----------------------------------------## readonly NOct="\e[0m" +readonly BOLDct="\e[1m" +readonly BLKct="\e[1;30m" readonly REDct="\e[1;31m" readonly GRNct="\e[1;32m" -readonly BLKct="\e[1;30m" readonly YLWct="\e[1;33m" readonly BLUEct="\e[1;34m" readonly MAGENTAct="\e[1;35m" readonly CYANct="\e[1;36m" readonly WHITEct="\e[1;37m" +readonly CRITct="\e[1;41m" +readonly InvREDct="\e[1;41m" +readonly InvGRNct="\e[1;42m" readonly ScriptFileName="${0##*/}" readonly ScriptFNameTag="${ScriptFileName%%.*}" @@ -260,15 +264,16 @@ _UserLogMsg_() } ##----------------------------------------## -## Modified by Martinski W. [2023-Dec-21] ## +## Modified by Martinski W. [2025-Feb-15] ## ##----------------------------------------## Say() { + local logMsg "$isInteractive" && printf "${1}\n" - # Clean out the "color escape sequences" from the log file # - local logMsg="$(echo "$1" | sed 's/\\\e\[0m//g ; s/\\\e\[[0-1];3[0-9]m//g')" + # Remove all "color escape sequences" from the system log file entries # + logMsg="$(echo "$1" | sed 's/\\\e\[[0-1]m//g ; s/\\\e\[[0-1];[3-4][0-9]m//g')" _UserLogMsg_ "$logMsg" - printf "$logMsg" | logger -t "[$(basename "$0")] $$" + printf "$logMsg" | logger -t "[${SCRIPT_NAME}] $$" } ##----------------------------------------------## @@ -1522,16 +1527,18 @@ _CheckForNewGUIVersionUpdate_() } ##----------------------------------------## -## Modified by Martinski W. [2025-Jan-06] ## +## Modified by Martinski W. [2025-Feb-15] ## ##----------------------------------------## _CurlFileDownload_() { if [ $# -lt 2 ] || [ -z "$1" ] || [ -z "$2" ] then return 1 ; fi - local retCode tempFilePathDL="${2}.DL.TMP" + local retCode=1 + local tempFilePathDL="${2}.DL.TMP" + local srceFilePathDL="${SCRIPT_URL_REPO}/$1" curl -LSs --retry 4 --retry-delay 5 --retry-connrefused \ - "$1" -o "$tempFilePathDL" + "$srceFilePathDL" -o "$tempFilePathDL" if [ $? -ne 0 ] || [ ! -s "$tempFilePathDL" ] || \ grep -iq "^404: Not Found" "$tempFilePathDL" then rm -f "$tempFilePathDL" ; retCode=1 @@ -1541,23 +1548,23 @@ _CurlFileDownload_() } ##----------------------------------------## -## Modified by Martinski W. [2025-Jan-06] ## +## Modified by Martinski W. [2025-Feb-15] ## ##----------------------------------------## _SCRIPTUPDATE_() { - local urlScriptVers theScriptVers extraParam="" + local extraParam="" _DownloadScriptFiles_() { local retCode - if _CurlFileDownload_ "${SCRIPT_URL_REPO}/version.txt" "$SCRIPTVERPATH" + if _CurlFileDownload_ "version.txt" "$SCRIPTVERPATH" then retCode=0 ; chmod 664 "$SCRIPTVERPATH" else retCode=1 Say "${REDct}**ERROR**${NOct}: Unable to download latest version file for $SCRIPT_NAME." fi - if _CurlFileDownload_ "${SCRIPT_URL_REPO}/${SCRIPT_NAME}.sh" "$ScriptFilePath" + if _CurlFileDownload_ "${SCRIPT_NAME}.sh" "$ScriptFilePath" then retCode=0 ; chmod 755 "$ScriptFilePath" else @@ -1570,19 +1577,19 @@ _SCRIPTUPDATE_() if [ $# -gt 0 ] && [ "$1" = "force" ] then printf "\n${CYANct}Force downloading latest script version...${NOct}\n" - theScriptVers="$SCRIPT_VERSION" - [ -s "$SCRIPTVERPATH" ] && theScriptVers="$(cat "$SCRIPTVERPATH")" - urlScriptVers="$(/usr/sbin/curl -LSs --retry 4 --retry-delay 5 "${SCRIPT_URL_REPO}/version.txt")" - printf "${CYANct}Downloading latest version ($urlScriptVers) of ${SCRIPT_NAME}${NOct}\n" + if ! _CheckForNewScriptUpdates_ -quietcheck + then + DLRepoVersion="$(/usr/sbin/curl -LSs --retry 4 --retry-delay 5 "${SCRIPT_URL_REPO}/version.txt")" + fi + if _CheckForNewGUIVersionUpdate_ "$SCRIPT_VERSION" "$DLRepoVersion" + then extraParam="install" + fi + printf "${CYANct}Downloading latest version [$DLRepoVersion] of ${SCRIPT_NAME}${NOct}\n" if _DownloadScriptFiles_ then printf "${CYANct}$SCRIPT_NAME was successfully updated.${NOct}\n\n" sleep 1 - [ -s "$SCRIPTVERPATH" ] && urlScriptVers="$(cat "$SCRIPTVERPATH")" - if [ $# -gt 1 ] && [ "$2" = "newgui" ] && \ - _CheckForNewGUIVersionUpdate_ "$theScriptVers" "$urlScriptVers" - then extraParam="install" ; fi _ReleaseLock_ exec "$ScriptFilePath" $extraParam exit 0 @@ -1609,7 +1616,7 @@ _SCRIPTUPDATE_() if _DownloadScriptFiles_ then printf "\n${CYANct}Download successful!${NOct}\n" - printf "$(date) - $SCRIPT_NAME - Successfully downloaded $SCRIPT_NAME v${DLRepoVersion}\n" + printf "$(date) - Successfully downloaded $SCRIPT_NAME v${DLRepoVersion}\n" fi _WaitForEnterKey_ return @@ -1627,7 +1634,7 @@ _SCRIPTUPDATE_() if _DownloadScriptFiles_ then - printf "\n$(date) - $SCRIPT_NAME - Successfully downloaded $SCRIPT_NAME v${DLRepoVersion}\n" + printf "\n$(date) - Successfully downloaded $SCRIPT_NAME v${DLRepoVersion}\n" printf "${CYANct}Update successful! Restarting script...${NOct}\n" sleep 1 _CheckForNewGUIVersionUpdate_ && extraParam="install" @@ -1647,18 +1654,16 @@ _SCRIPTUPDATE_() } ##----------------------------------------## -## Modified by Martinski W. [2025-Jan-01] ## +## Modified by Martinski W. [2025-Feb-15] ## ##----------------------------------------## _CheckForNewScriptUpdates_() { - local extraParam="" - echo DLRepoVersion="$SCRIPT_VERSION" [ -s "$SCRIPTVERPATH" ] && DLRepoVersion="$(cat "$SCRIPTVERPATH")" rm -f "$SCRIPTVERPATH" - if ! _CurlFileDownload_ "${SCRIPT_URL_REPO}/version.txt" "$SCRIPTVERPATH" + if ! _CurlFileDownload_ "version.txt" "$SCRIPTVERPATH" then Say "${REDct}**ERROR**${NOct}: Unable to download latest version file for $SCRIPT_NAME." scriptUpdateNotify=0 @@ -1680,11 +1685,14 @@ _CheckForNewScriptUpdates_() then scriptUpdateNotify="New script update available. ${REDct}v${SCRIPT_VERSION}${NOct} --> ${GRNct}v${DLRepoVersion}${NOct}" + + if [ $# -gt 0 ] && [ "$1" = "-quietcheck" ] + then return 0 + fi Say "$myLAN_HostName - A new script version update (v$DLRepoVersion) is available to download." if [ "$ScriptAutoUpdateSetting" = "ENABLED" ] then - _CheckForNewGUIVersionUpdate_ && extraParam="newgui" - _SCRIPTUPDATE_ force $extraParam + _SCRIPTUPDATE_ force fi else scriptUpdateNotify=0 @@ -1692,9 +1700,9 @@ ${REDct}v${SCRIPT_VERSION}${NOct} --> ${GRNct}v${DLRepoVersion}${NOct}" return 0 } -##----------------------------------------------## -## Added/Modified by Martinski W. [2023-Nov-22] ## -##----------------------------------------------## +##----------------------------------------## +## Modified by Martinski W. [2023-Nov-22] ## +##----------------------------------------## _GetLatestFWUpdateVersionFromRouter_() { local retCode=0 webState newVersionStr @@ -6227,8 +6235,9 @@ _CheckTimeToUpdateFirmware_() Say "The firmware update is expected to occur on ${GRNct}${nextCronTimeSecs}${NOct}." echo "" - # Check if running in a menu environment # - if "$isInteractive" && _WaitForYESorNO_ "Would you like to proceed with the update now?" + "$isInteractive" && \ + printf "\n${BOLDct}Would you like to proceed with the update now${NOct}" + if _WaitForYESorNO_ then return 0 else return 1 fi @@ -6819,9 +6828,9 @@ _RunBackupmon_() return 0 } -##------------------------------------------## -## Modified by ExtremeFiretop [2024-Oct-13] ## -##------------------------------------------## +##----------------------------------------## +## Modified by Martinski W. [2025-Feb-15] ## +##----------------------------------------## _RunOfflineUpdateNow_() { local retCode @@ -6941,7 +6950,7 @@ _RunOfflineUpdateNow_() _RunFirmwareUpdateNow_ _ClearOfflineUpdateState_ else - Say "${REDct}**ERROR**${NOct}: No firmware release URL was found for [$PRODUCT_ID] router model." + Say "${REDct}**ERROR**${NOct}: No firmware release URL was found for [$MODEL_ID] router model." _ClearOfflineUpdateState_ 1 return 1 fi @@ -6955,9 +6964,9 @@ _RunOfflineUpdateNow_() fi } -##------------------------------------------## -## Modified by ExtremeFiretop [2024-Jul-31] ## -##------------------------------------------## +##----------------------------------------## +## Modified by Martinski W. [2025-Feb-15] ## +##----------------------------------------## _RunFirmwareUpdateNow_() { # Double-check the directory exists before using it # @@ -7077,7 +7086,7 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or if ! release_version="$(_GetLatestFWUpdateVersionFromRouter_)" || \ ! _CheckNewUpdateFirmwareNotification_ "$current_version" "$release_version" then - Say "No new firmware version update is found for [$PRODUCT_ID] router model." + Say "No new firmware version update is found for [$MODEL_ID] router model." "$inMenuMode" && _WaitForEnterKey_ "$mainMenuReturnPromptStr" return 1 fi @@ -7102,7 +7111,7 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or release_version="$1" release_link="$2" else - Say "${REDct}**ERROR**${NOct}: No firmware release URL was found for [$PRODUCT_ID] router model." + Say "${REDct}**ERROR**${NOct}: No firmware release URL was found for [$MODEL_ID] router model." "$inMenuMode" && _WaitForEnterKey_ "$mainMenuReturnPromptStr" return 1 fi @@ -8058,7 +8067,7 @@ check_version_support _CheckEMailConfigFileFromAMTM_ 0 ##----------------------------------------## -## Modified by Martinski W. [2024-Dec-31] ## +## Modified by Martinski W. [2025-Feb-15] ## ##----------------------------------------## if [ $# -gt 0 ] && [ -n "$1" ] then @@ -8082,7 +8091,7 @@ then ;; checkupdates) _CheckForNewScriptUpdates_ ;; - forceupdate) _SCRIPTUPDATE_ force "$([ $# -gt 1 ] && echo "$2" || echo)" + forceupdate) _SCRIPTUPDATE_ force ;; develop) _ChangeToDev_ ;; @@ -8471,7 +8480,7 @@ _InvalidMenuSelection_() } ##----------------------------------------## -## Modified by Martinski W. [2024-Jul-03] ## +## Modified by Martinski W. [2025-Feb-15] ## ##----------------------------------------## _ShowMainMenu_() { @@ -8490,29 +8499,34 @@ _ShowMainMenu_() printf "${YLWct}============ By ExtremeFiretop & Martinski W. ============${NOct}\n\n" # New Script Update Notification # - if [ "$scriptUpdateNotify" != "0" ]; then - Say "${REDct}*WARNING*:${NOct} ${scriptUpdateNotify}\n" + if [ "$scriptUpdateNotify" != "0" ] + then + Say "${InvREDct}*NOTICE*:${NOct} ${scriptUpdateNotify}" + echo fi # Unsupported Model Check # if "$routerModelCheckFailed" then Say "${REDct}*WARNING*:${NOct} The current router model is not supported by this script. - Please uninstall.\n" + Please uninstall." + echo fi if "$MinFirmwareVerCheckFailed" then Say "${REDct}*WARNING*:${NOct} The current firmware version is below the minimum supported. - Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or higher to use this script.\n" + Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or higher to use this script." + echo fi if ! _HasRouterMoreThan256MBtotalRAM_ && ! _ValidateUSBMountPoint_ "$FW_ZIP_BASE_DIR" then Say "${REDct}*WARNING*:${NOct} Limited RAM detected (256MB). - A USB drive is required for F/W updates.\n" + A USB drive is required for F/W updates." + echo fi - arrowStr=" ${REDct}<<---${NOct}" + arrowStr=" ${InvREDct} <<<< ${NOct}" _Calculate_NextRunTime_ @@ -8531,14 +8545,14 @@ _ShowMainMenu_() if [ "$HIDE_ROUTER_SECTION" = "false" ] then if ! FW_NewUpdateVerStr="$(_GetLatestFWUpdateVersionFromRouter_ 1)" - then FW_NewUpdateVerStr="${REDct}NONE FOUND${NOct}" - else FW_NewUpdateVerStr="${GRNct}${FW_NewUpdateVerStr}${NOct}$arrowStr" + then FW_NewUpdateVerStr=" ${REDct}NONE FOUND${NOct}" + else FW_NewUpdateVerStr="${InvGRNct} ${FW_NewUpdateVerStr} ${NOct}$arrowStr" fi printf "\n Router's Product Name/Model ID: ${FW_RouterModelID}${padStr}(H)ide" printf "\n USB-Attached Storage Connected: $USBConnected" printf "\n F/W Variant Configuration Found: $FirmwareFlavor" printf "\n F/W Version Currently Installed: $FW_InstalledVerStr" - printf "\n F/W Update Version Available: $FW_NewUpdateVerStr" + printf "\n F/W Update Version Available: $FW_NewUpdateVerStr" printf "\n F/W Update Estimated Run Date: $ExpectedFWUpdateRuntime" else printf "\n Router's Product Name/Model ID: ${FW_RouterModelID}${padStr}(S)how" @@ -8553,11 +8567,11 @@ _ShowMainMenu_() [ -z "$FW_UpdateCheckState" ] && FW_UpdateCheckState=0 if [ "$FW_UpdateCheckState" -eq 0 ] then - printf "\n ${GRNct}3${NOct}. Toggle F/W Update Check" - printf "\n${padStr}[Currently ${REDct}DISABLED${NOct}]" + printf "\n ${GRNct}3${NOct}. Toggle Automatic F/W Update Checks" + printf "\n${padStr}[Currently ${InvREDct} DISABLED ${NOct}]" else - printf "\n ${GRNct}3${NOct}. Toggle F/W Update Check" - printf "\n${padStr}[Currently ${GRNct}ENABLED${NOct}]" + printf "\n ${GRNct}3${NOct}. Toggle Automatic F/W Update Checks" + printf "\n${padStr}[Currently ${InvGRNct} ENABLED ${NOct}]" fi printf "\n${padStr}[Last Notification Date: $notificationStr]\n" @@ -8589,7 +8603,7 @@ _ShowMainMenu_() if [ "$scriptUpdateNotify" != "0" ] then printf "\n ${GRNct}up${NOct}. Update $SCRIPT_NAME Script" - printf "\n${padStr}[Version ${GRNct}${DLRepoVersion}${NOct} Available for Download]\n" + printf "\n${padStr}[Version ${InvGRNct} ${DLRepoVersion} ${NOct} Available for Download]\n" else printf "\n ${GRNct}up${NOct}. Force Update $SCRIPT_NAME Script" printf "\n${padStr}[No Update Available]\n" From 5f3d666fa68dfaa88dcfb050693eb890f2bac56b Mon Sep 17 00:00:00 2001 From: Martinski <119833648+Martinski4GitHub@users.noreply.github.com> Date: Mon, 17 Feb 2025 02:44:46 -0800 Subject: [PATCH 08/14] Fixed "Toggle F/W Build Type" Error Fixed "buildtypechoice: parameter not set" error found when using the CLI menu option to "Toggle F/W Build Type" and user simply types the key. --- MerlinAU.sh | 81 +++++++++++++++++++++++++++-------------------------- README.md | 2 +- 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index 84f5db6f..1706456a 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -4,7 +4,7 @@ # # Original Creation Date: 2023-Oct-01 by @ExtremeFiretop. # Official Co-Author: @Martinski W. - Date: 2023-Nov-01 -# Last Modified: 2025-Feb-15 +# Last Modified: 2025-Feb-16 ################################################################### set -u @@ -72,6 +72,7 @@ readonly WHITEct="\e[1;37m" readonly CRITct="\e[1;41m" readonly InvREDct="\e[1;41m" readonly InvGRNct="\e[1;42m" +readonly InvBYLWct="\e[30;103m" readonly ScriptFileName="${0##*/}" readonly ScriptFNameTag="${ScriptFileName%%.*}" @@ -3810,50 +3811,52 @@ _Toggle_Auto_Backups_() _WaitForEnterKey_ } -##------------------------------------------## -## Modified by ExtremeFiretop [2024-Feb-18] ## -##------------------------------------------## +##----------------------------------------## +## Modified by Martinski W. [2025-Feb-16] ## +##----------------------------------------## _ChangeBuildType_TUF_() { local doReturnToMenu buildtypechoice - printf "Changing Flash Build Type...\n" # Use Get_Custom_Setting to retrieve the previous choice previous_choice="$(Get_Custom_Setting "TUFBuild")" - # If the previous choice is not set, default to 'n' + # If the previous choice is not set, default to 'n' # if [ "$previous_choice" = "TBD" ]; then previous_choice="n" fi - # Convert previous choice to a descriptive text + # Convert previous choice to a descriptive text # if [ "$previous_choice" = "y" ]; then display_choice="TUF Build" else display_choice="Pure Build" fi - - printf "\nCurrent Build Type: ${GRNct}$display_choice${NOct}.\n" + printf "\n\nCurrent Build Type: ${GRNct}${display_choice}${NOct}.\n" doReturnToMenu=false while true do printf "\n${SEPstr}" printf "\nChoose your preferred option for the build type to flash:\n" - printf "\n ${GRNct}1${NOct}. Original ${REDct}TUF${NOct} themed user interface${NOct}\n" - printf "\n ${GRNct}2${NOct}. Pure ${GRNct}non-TUF${NOct} themed user interface ${GRNct}(Recommended)${NOct}\n" + printf "\n ${GRNct}1${NOct}. Original ${REDct}TUF${NOct} themed user interface" + printf "\n ${REDct}(Applies only if TUF F/W is available; otherwise, defaults to Pure build)${NOct}\n" + printf "\n ${GRNct}2${NOct}. Pure ${GRNct}Non-TUF${NOct} themed user interface" + printf "\n ${GRNct}(Recommended)${NOct}\n" printf "\n ${GRNct}e${NOct}. Exit to Advanced Menu\n" printf "${SEPstr}\n" - printf "[$display_choice] Enter selection: " + printf "[${GRNct}${display_choice}${NOct}] Enter selection: " read -r choice - [ -z "$choice" ] && break - - if echo "$choice" | grep -qE "^(e|exit|Exit)$" + if [ -z "$choice" ] || echo "$choice" | grep -qE "^(e|exit|Exit)$" then doReturnToMenu=true ; break ; fi case $choice in - 1) buildtypechoice="y" ; break + 1) buildtypechoice="y" + printf "\n${InvBYLWct} NOTE: ${NOct}\n" + printf "${CYANct}The TUF build will apply only if a compatible TUF firmware image is available." + printf "\nOtherwise, the Pure ${GRNct}Non-TUF${NOct}${CYANct} build will be used instead.${NOct}\n" + break ;; 2) buildtypechoice="n" ; break ;; @@ -3870,50 +3873,52 @@ _ChangeBuildType_TUF_() _WaitForEnterKey_ "$advnMenuReturnPromptStr" } -##------------------------------------------## -## Modified by ExtremeFiretop [2024-Feb-18] ## -##------------------------------------------## +##----------------------------------------## +## Modified by Martinski W. [2025-Feb-16] ## +##----------------------------------------## _ChangeBuildType_ROG_() { local doReturnToMenu buildtypechoice - printf "Changing Flash Build Type...\n" # Use Get_Custom_Setting to retrieve the previous choice previous_choice="$(Get_Custom_Setting "ROGBuild")" - # If the previous choice is not set, default to 'n' + # If the previous choice is not set, default to 'n' # if [ "$previous_choice" = "TBD" ]; then previous_choice="n" fi - # Convert previous choice to a descriptive text + # Convert previous choice to a descriptive text # if [ "$previous_choice" = "y" ]; then display_choice="ROG Build" else display_choice="Pure Build" fi - - printf "\nCurrent Build Type: ${GRNct}$display_choice${NOct}.\n" + printf "\n\nCurrent Build Type: ${GRNct}${display_choice}${NOct}.\n" doReturnToMenu=false while true do printf "\n${SEPstr}" printf "\nChoose your preferred option for the build type to flash:\n" - printf "\n ${GRNct}1${NOct}. Original ${REDct}ROG${NOct} themed user interface${NOct}\n" - printf "\n ${GRNct}2${NOct}. Pure ${GRNct}non-ROG${NOct} themed user interface ${GRNct}(Recommended)${NOct}\n" + printf "\n ${GRNct}1${NOct}. Original ${REDct}ROG${NOct} themed user interface" + printf "\n ${REDct}(Applies only if ROG F/W is available; otherwise, defaults to Pure build)${NOct}\n" + printf "\n ${GRNct}2${NOct}. Pure ${GRNct}Non-ROG${NOct} themed user interface" + printf "\n ${GRNct}(Recommended)${NOct}\n" printf "\n ${GRNct}e${NOct}. Exit to Advanced Menu\n" printf "${SEPstr}\n" - printf "[$display_choice] Enter selection: " + printf "[${GRNct}${display_choice}${NOct}] Enter selection: " read -r choice - [ -z "$choice" ] && break - - if echo "$choice" | grep -qE "^(e|exit|Exit)$" + if [ -z "$choice" ] || echo "$choice" | grep -qE "^(e|exit|Exit)$" then doReturnToMenu=true ; break ; fi case $choice in - 1) buildtypechoice="y" ; break + 1) buildtypechoice="y" + printf "\n${InvBYLWct} NOTE: ${NOct}\n" + printf "${CYANct}The ROG build will apply only if a compatible ROG firmware image is available." + printf "\nOtherwise, the Pure ${GRNct}Non-ROG${NOct}${CYANct} build will be used instead.${NOct}\n" + break ;; 2) buildtypechoice="n" ; break ;; @@ -8625,7 +8630,7 @@ _ShowMainMenu_() } ##----------------------------------------## -## Modified by Martinski W. [2024-Dec-22] ## +## Modified by Martinski W. [2025-Feb-16] ## ##----------------------------------------## _ShowAdvancedOptionsMenu_() { @@ -8689,7 +8694,6 @@ _ShowAdvancedOptionsMenu_() then if [ "$fwInstalledBaseVers" -le 3004 ] then - # Retrieve the current build type setting current_build_type="$(Get_Custom_Setting "TUFBuild")" # Convert the setting to a descriptive text @@ -8703,7 +8707,7 @@ _ShowAdvancedOptionsMenu_() if echo "$PRODUCT_ID" | grep -q "^TUF-" then - printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type" + printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type Preference" if [ "$current_build_type_menu" = "NOT SET" ] then printf "\n${padStr}[Current Build Type: ${REDct}${current_build_type_menu}${NOct}]\n" else printf "\n${padStr}[Current Build Type: ${GRNct}${current_build_type_menu}${NOct}]\n" @@ -8711,7 +8715,6 @@ _ShowAdvancedOptionsMenu_() fi elif [ "$fwInstalledBaseVers" -ge 3006 ] then - # Retrieve the current build type setting local current_build_typerog="$(Get_Custom_Setting "ROGBuild")" # Convert the setting to a descriptive text @@ -8725,14 +8728,13 @@ _ShowAdvancedOptionsMenu_() if echo "$PRODUCT_ID" | grep -q "^GT-" then - printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type" + printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type Preference" if [ "$current_build_type_menurog" = "NOT SET" ] then printf "\n${padStr}[Current Build Type: ${REDct}${current_build_type_menurog}${NOct}]\n" else printf "\n${padStr}[Current Build Type: ${GRNct}${current_build_type_menurog}${NOct}]\n" fi fi - # Retrieve the current build type setting local current_build_typetuf="$(Get_Custom_Setting "TUFBuild")" # Convert the setting to a descriptive text @@ -8746,7 +8748,7 @@ _ShowAdvancedOptionsMenu_() if echo "$PRODUCT_ID" | grep -q "^TUF-" then - printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type" + printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type Preference" if [ "$current_build_type_menutuf" = "NOT SET" ] then printf "\n${padStr}[Current Build Type: ${REDct}${current_build_type_menutuf}${NOct}]\n" else printf "\n${padStr}[Current Build Type: ${GRNct}${current_build_type_menutuf}${NOct}]\n" @@ -8756,7 +8758,6 @@ _ShowAdvancedOptionsMenu_() else if [ "$fwInstalledBaseVers" -le 3004 ] then - # Retrieve the current build type setting current_build_type="$(Get_Custom_Setting "ROGBuild")" # Convert the setting to a descriptive text @@ -8770,7 +8771,7 @@ _ShowAdvancedOptionsMenu_() if echo "$PRODUCT_ID" | grep -q "^GT-" then - printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type" + printf "\n ${GRNct}bt${NOct}. Toggle F/W Build Type Preference" if [ "$current_build_type_menu" = "NOT SET" ] then printf "\n${padStr}[Current Build Type: ${REDct}${current_build_type_menu}${NOct}]\n" else printf "\n${padStr}[Current Build Type: ${GRNct}${current_build_type_menu}${NOct}]\n" diff --git a/README.md b/README.md index 6d084cc5..9383c3ca 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MerlinAU - AsusWRT-Merlin Firmware Auto Updater ## v1.3.10 -## 2025-Jan-06 +## 2025-Feb-?? ![image](https://github.com/user-attachments/assets/185f9fe4-acdb-419a-8154-ab6fa6e0fd46) ![image](https://github.com/user-attachments/assets/8f22818d-2118-4c47-a54a-e54fb147fd6b) From 5296f3b39adafb33bd5407a72d31a612f23c010d Mon Sep 17 00:00:00 2001 From: Joel Samson Date: Mon, 17 Feb 2025 15:49:31 -0500 Subject: [PATCH 09/14] Update MerlinAU.sh --- MerlinAU.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index 1706456a..76d64f1f 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -3580,10 +3580,16 @@ _CopyGnutonFiles_() _CheckOnlineFirmwareSHA256_() { # Fetch the latest SHA256 checksums from ASUSWRT-Merlin website # - checksums="$(curl -Ls --retry 4 --retry-delay 5 --retry-connrefused \ - https://www.asuswrt-merlin.net/download | \ - sed -n '/<.*>SHA256 signatures:<\/.*>/,/<\/pre>/p' | \ - sed -n '/].*>/,/<\/pre>/p' | sed -e 's/<[^>].*>//g')" + checksums="$( + curl -Ls --retry 4 --retry-delay 5 --retry-connrefused \ + https://www.asuswrt-merlin.net/download | + sed -n '/<.*>SHA256 signatures:<\/.*>/,/<\/pre>/p' | + sed -n '/]*>/,/<\/pre>/p' | + sed -e 's/<[^>]*>//g' | + tr -d '\r' | + sed -e 's/^[[:space:]]*//; s/[[:space:]]*$//' | + sed -e 's/SHA256 signatures:Latest release://' + )" if [ -z "$checksums" ] then From 94da9fbf7b06fc4ab779ce9e54cfb022aa68d209 Mon Sep 17 00:00:00 2001 From: Martinski <119833648+Martinski4GitHub@users.noreply.github.com> Date: Mon, 17 Feb 2025 21:18:38 -0800 Subject: [PATCH 10/14] Improved SHA256 Signature Extraction Code improvements for extracting SHA256 signatures. --- MerlinAU.sh | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/MerlinAU.sh b/MerlinAU.sh index 76d64f1f..f8421d20 100644 --- a/MerlinAU.sh +++ b/MerlinAU.sh @@ -4,7 +4,7 @@ # # Original Creation Date: 2023-Oct-01 by @ExtremeFiretop. # Official Co-Author: @Martinski W. - Date: 2023-Nov-01 -# Last Modified: 2025-Feb-16 +# Last Modified: 2025-Feb-17 ################################################################### set -u @@ -3574,22 +3574,17 @@ _CopyGnutonFiles_() return 0 } -##------------------------------------------## -## Modified by ExtremeFiretop [2024-Jul-24] ## -##------------------------------------------## +##----------------------------------------## +## Modified by Martinski W. [2025-Feb-17] ## +##----------------------------------------## _CheckOnlineFirmwareSHA256_() { # Fetch the latest SHA256 checksums from ASUSWRT-Merlin website # - checksums="$( - curl -Ls --retry 4 --retry-delay 5 --retry-connrefused \ - https://www.asuswrt-merlin.net/download | - sed -n '/<.*>SHA256 signatures:<\/.*>/,/<\/pre>/p' | - sed -n '/]*>/,/<\/pre>/p' | - sed -e 's/<[^>]*>//g' | - tr -d '\r' | - sed -e 's/^[[:space:]]*//; s/[[:space:]]*$//' | - sed -e 's/SHA256 signatures:Latest release://' - )" + checksums="$(curl -Ls --retry 4 --retry-delay 5 --retry-connrefused \ + https://www.asuswrt-merlin.net/download | + sed -n '/<.*>SHA256 signatures:<\/.*>/,/<\/pre>/p' | + sed -n '/].*>/,/<\/pre>/p' | + sed -e 's/<[^>].*>//g; s/^[[:space:]]*//; s/[[:space:]]*$//')" if [ -z "$checksums" ] then @@ -3600,9 +3595,9 @@ _CheckOnlineFirmwareSHA256_() if [ -f "$firmware_file" ] then - fw_sig="$(openssl sha256 "$firmware_file" | cut -d' ' -f2)" + fw_sig="$(openssl sha256 "$firmware_file" | awk -F ' ' '{print $2}')" # Extract the corresponding signature for the firmware file from the fetched checksums # - dl_sig="$(echo "$checksums" | grep "$(basename "$firmware_file")" | cut -d' ' -f1)" + dl_sig="$(echo "$checksums" | grep "$(basename "$firmware_file")" | awk -F ' ' '{print $1}')" if [ "$fw_sig" != "$dl_sig" ] then Say "${REDct}**ERROR**${NOct}: SHA256 signature from extracted firmware file does not match the SHA256 signature from the website." @@ -3621,14 +3616,14 @@ _CheckOnlineFirmwareSHA256_() } ##----------------------------------------## -## Modified by Martinski W. [2024-Jul-31] ## +## Modified by Martinski W. [2025-Feb-17] ## ##----------------------------------------## _CheckOfflineFirmwareSHA256_() { if [ -f "sha256sum.sha256" ] && [ -f "$firmware_file" ] then - fw_sig="$(openssl sha256 "$firmware_file" | cut -d' ' -f2)" - dl_sig="$(grep "$firmware_file" sha256sum.sha256 | cut -d' ' -f1)" + fw_sig="$(openssl sha256 "$firmware_file" | awk -F ' ' '{print $2}')" + dl_sig="$(grep "$firmware_file" sha256sum.sha256 | awk -F ' ' '{print $1}')" if [ "$fw_sig" != "$dl_sig" ] then echo From 47898fa842a0f8add13a0d556215c6092ab648b6 Mon Sep 17 00:00:00 2001 From: Joel Samson Date: Tue, 18 Feb 2025 12:02:29 -0500 Subject: [PATCH 11/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9383c3ca..80ea6e01 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MerlinAU - AsusWRT-Merlin Firmware Auto Updater ## v1.3.10 -## 2025-Feb-?? +## 2025-Feb-18 ![image](https://github.com/user-attachments/assets/185f9fe4-acdb-419a-8154-ab6fa6e0fd46) ![image](https://github.com/user-attachments/assets/8f22818d-2118-4c47-a54a-e54fb147fd6b) From 5f5fa1ba4ba2d143787bbd2225c70881255e2a73 Mon Sep 17 00:00:00 2001 From: Joel Samson Date: Tue, 18 Feb 2025 12:06:41 -0500 Subject: [PATCH 12/14] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 80ea6e01..cd96fe19 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ ## v1.3.10 ## 2025-Feb-18 -![image](https://github.com/user-attachments/assets/185f9fe4-acdb-419a-8154-ab6fa6e0fd46) -![image](https://github.com/user-attachments/assets/8f22818d-2118-4c47-a54a-e54fb147fd6b) -![image](https://github.com/user-attachments/assets/bd2f41b6-230d-4ef8-ad41-e7a2d8a77746) -![image](https://github.com/user-attachments/assets/a064e3d1-e615-4021-a5de-127cdb6cb8e4) +![image](https://github.com/user-attachments/assets/2eebe686-364a-4fb1-9493-e6b91c23b9fd) +![image](https://github.com/user-attachments/assets/5ca4587f-5b6e-45a6-9c2d-a889b91f8368) +![image](https://github.com/user-attachments/assets/959d7bb6-20b4-4e97-ab3e-b7b90cc08744) +![image](https://github.com/user-attachments/assets/2e92af06-a6b1-4573-9a89-6986e739b514) ## SUPPORTED MERLIN MODELS (Multi-image models) - i.e. Any model that uses a .w or a .pkgtb file From 766e37186ec0c52ab579c2de273d1af7cbd00193 Mon Sep 17 00:00:00 2001 From: Joel Samson Date: Tue, 18 Feb 2025 12:09:48 -0500 Subject: [PATCH 13/14] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index cd96fe19..e6273a67 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,12 @@ To install MerlinAutoUpdate, follow these steps: Enable SSH on your router if not already enabled. Use your preferred SSH client to connect to the router. +*MerlinAU is now available through AMTM!* +1. Simply connect to the router via SSH and type: "amtm" to load AMTM +2. Select option (i) to view the list of available applications. +3. MerlinAU is option (8) from AMTM. + +*Manual Installation* Download the script to your router: Copy and paste: ```bash From ba7a51c74b9f87b868550cd61258be47108256e6 Mon Sep 17 00:00:00 2001 From: Joel Samson Date: Tue, 18 Feb 2025 12:10:27 -0500 Subject: [PATCH 14/14] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index e6273a67..c32fe0d0 100644 --- a/README.md +++ b/README.md @@ -125,8 +125,7 @@ Use your preferred SSH client to connect to the router. 3. MerlinAU is option (8) from AMTM. *Manual Installation* -Download the script to your router: -Copy and paste: +1. To Download the script to your router, Copy and paste: ```bash curl --retry 3 "https://raw.githubusercontent.com/ExtremeFiretop/MerlinAutoUpdate-Router/master/MerlinAU.sh" -o "/jffs/scripts/MerlinAU.sh" && chmod +x "/jffs/scripts/MerlinAU.sh" ```