1
\$\begingroup\$

I have written a script to reduce/lower the version number stored in opkg status file using small shell script, This will enable us to force the opkg to install same version of a Debian package again.

Versions stored in the opkg files are as follows,

Version: 00.03.00a002
Version: 2013.07.001
Version: 2013.07.001
Version: 3.12.002

And my script is as shown below, This script would run on the embedded board which is having busybox based sh shell. I have put bash tag to reach more people.

Script edits either 1st version number or 2nd version number..I didn't take third because sometimes that would contain alphanumeric value and I am uncomfortable with handling hex subtraction.

#!/bin/sh

#Small script to Lower firmware version 

OPKG_STATUS_FILE="/var/lib/opkg/status"
stamp=$(date +%s)
BACKUP_OPKG_STATUS_FILE="/var/lib/opkg/status_${stamp}"


#Creating backup file so that we can get back actual version if we want
cp ${OPKG_STATUS_FILE} ${BACKUP_OPKG_STATUS_FILE}
echo "${BACKUP_OPKG_STATUS_FILE} file created"

#clear original status file
:> ${OPKG_STATUS_FILE}

while IFS=' ' read -r line || [ -n "${line}" ];do
    ver_found=""
    ver_found=$(echo "${line}" | grep -i "Version")

    if [ ! -z "${ver_found}" ];then
        ver_extracted=""
        new_line=""
        for i in 1 2;do
            ver_extracted=$(echo "${line}" | grep -i "Version" | cut -d ':' -f 2 | cut -d '.' -f ${i})
            if [ ! -z "${ver_extracted}" ];then
            {
                #reduce version number
                if [ "${ver_extracted}" -gt 0 ];then
                    new_version=$(printf "%02d %02d" "${ver_extracted}" "01" | awk '{ printf "%.0f", $1 - $2 }')
                    new_line=$(echo ${line} | sed -e "s:${ver_extracted}:${new_version}:I")
                    line="${new_line}"
                else
                    continue
                fi
                break
            }
            fi
        done
    fi
    echo "${line}" >> "${OPKG_STATUS_FILE}"
done < "${BACKUP_OPKG_STATUS_FILE}"

I wanted to ask

  1. if there is a better method for doing this.
  2. One problem what I observed with my script is 03 is reduced and replaced with 2 instead of 02
    I need to keep versions digits same, any suggestion for that ?
\$\endgroup\$
  • \$\begingroup\$ The problem you describe sounds like a bug, which would make this off-topic for CR. \$\endgroup\$ – BCdotWEB Jan 8 '16 at 13:28
  • \$\begingroup\$ how about better/simpler method any suggestions? \$\endgroup\$ – AnkurTank Jan 8 '16 at 13:57
1
\$\begingroup\$

Since you're already using awk in there, it would be better to rewrite all the echo - grep - sed processing with a single awk. In particular, the entire while loop in the middle can be replaced with this:

awk -F '[:. ]' '/^Version: / {
  num1 = $3;
  num2 = $4;
  if (num1 > 0) {
    gsub(num1, num1 - 1);
    print;
  } else if (num2 > 0) {
    gsub(num2, num2 - 1);
    print;
  }
}
' "${BACKUP_OPKG_STATUS_FILE}" >> "${OPKG_STATUS_FILE}"

This produces slightly different (I think better) output than your original, and with the number of sub-processes greatly reduced, it's a lot more efficient.

\$\endgroup\$
  • \$\begingroup\$ this doesn't work on busybox shell. :( awk: cmd. line:2: Call to undefined function \$\endgroup\$ – AnkurTank Jan 8 '16 at 16:02
  • 1
    \$\begingroup\$ Hm, that's probably because of the strtonum function I used. I removed it, it's probably not really needed (not for your example data anyway) \$\endgroup\$ – janos Jan 8 '16 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.