Script to list installed packages? (for simplifying sysupgrade)

During a sysupgrade, all previously-installed packages are lost. It's a drag to find and install them. It would be great to have an automated way to retain the list of scripts.

On the OpenWRT forum (at there is a script that purports to do this, but it does not work with LEDE 17.01.2. That script refers to a non-existent opkg config file (it has moved) and doesn't seem to understand the current format - the output is empty. Nonetheless, it appears to have a good user interface so maybe it could be tweaked to current opkg format.

Has anyone found/produced a script that lists installed pkgs? Thanks.

Update: The script does work as desired. See the script in the OpenWrtScripts repo on Github

Sysupgrade should not remove packages or reset something.
Only if -n flag is used factory reset will be made.

Also opkg can show you installed packages

@richb-hanover The script you linked seems to work for me.

First you call it with "write" and it creates an /etc/config/opkg.installed file. This file is simply the output of opkg list-installed. Such a file never was part of opkg's routine activities. Storing the file under /etc/config will have it survive a sysupgrade. Then after upgrading, you'd run the script again with the "install" action and it will parse the previously stored file and re-install any packages that are missing.

Granted I didn't actually upgrade, but I did write and the file was created. Then I removed a package on purpose and the script's install option was able to re-install it.

When was the last time you actually tried this?

1 Like

Little script that shows installed packages (man, i thought it was harder)


install_time=$(opkg status kernel | grep Installed-Time | sed "s/Installed-Time: //")

opkg list-installed | awk -F " " '{print $1}' > /tmp/installed_pkg

while read index
    loop_inst_time=$(opkg status $index | grep Installed-Time | sed "s/Installed-Time: //")
    is_user_installed=$(opkg status $index | grep "Status:" | grep "user")
    if [ "$loop_inst_time" -ne "$install_time" ] && [ -n "$is_user_installed" ]; then
        echo $index
done < /tmp/installed_pkg

The second condition in the test helps in getting just the user installed packages, with no dependencies in output.

Been a while,usually I factory reset when sysupgrading

@mk24 Right you are. On a second read, I see that the script provides a good tool for archiving the installed scripts, and re-installing after the upgrade.

Update: Here are the major commands of the script:

sh write use before sysupgrade to save the current set of packages

sh install use after successful sysupgrade, to restore those packages

sh help display full help information for the script

For ease of reading/use, I copied it from the forum into my OpenWrtScripts repo on github at


Here my version of the script to show the installed packages:


install_time=`opkg status kernel | awk '$1 == "Installed-Time:" { print $2 }'`
opkg status | awk '$1 == "Package:" {package = $2} \
$1 == "Status:" { user_inst = / user/ && / installed/ } \
$1 == "Installed-Time:" && $2 != '$install_time' && user_inst { print package }'

Really one of those codes would need to be integrated as a opkg command, as for now only users who go for discussions here or on OpenWRT forum gets these scripts.

Nice idea on the removal of temporary file.

I'm not sure that this needs to be baked into the opkg command.

An alternative would be to create a convention of putting "useful scripts" into a well known directory in every LEDE/OpenWrt distribution, so that documentation writers can refer to them. (That was my goal for the OpenWrtScripts repo - a collection of scripts that I found to be useful...)

The problem stays in opkg not tagging the packages as explicitly installed by the user as other package managers do, so it goes by workaround in getting the wanted result.

Having one of those scripts as an internal opkg command would not require a rewrite of opkg itself.

I wonder if this could be done by spreading more the documentation ( as making an information hub of it.

Sorry to resurrect an old thread, but are these scripts still applicable to the latest Master SNAPSHOT builds?

They look like a great way to quicken the upgrade process.
I'm new to OpenWrt coming from DD-WRT.
I have a WRT32X running OpenWrt SNAPSHOT r7301-b8bdeac / LuCI Master (git-18.169.62979-e380cf5)
Thanks in advance!

It would actually be cool, if the builtin backup and sysupgrade function could include the export-installedapps-list-script and then auto-install the list on system upgrades.

Auto-install will not happen, as that could be dangerous if e.g. growing kernel space requirements has decreased the space available for packages.

What about the above mentioned scripts? Specifically:
sh write
sh install

The last update was 9 months ago. A lot of changes to OpenWrt since then. I am just wondering if anything needs to be modified or if they can be used as is.

on OpenWrt 18.06RC1
I got no output and no error feedback from

But the 4-liner of ehlers in this thread works like a charm.
I've just remove the line breaks and added a "sort" - Here is ehlers MVP code as a copy&paste 1-liner, you can just paste that to an OpenWrt SSH prompt:

install_time=$(opkg status kernel|awk '$1=="Installed-Time:" {print $2}');opkg status|awk '$1=="Package:" {package=$2} $1=="Status:" {user_inst=/ user/ && / installed/} $1=="Installed-Time:" && $2!='$install_time' && user_inst {print package}'|sort

And here is a slightly modified version that will now output a fully runnable one liner that when run will install/update exacly those packages:

echo -n "opkg update;opkg install ";install_time=$(opkg status kernel|awk '$1=="Installed-Time:" {print $2}');opkg status|awk '$1=="Package:" {package=$2} $1=="Status:" {user_inst=/ user/ && / installed/} $1=="Installed-Time:" && $2!='$install_time' && user_inst {print package}'|sort|sed ':a;N;$!ba;s/\n/ /g'

Can someone confirm that this also works on LEDE v17?
(I currently have no more v17 devices running, so I can't test it now)
....I can easily add this to the OpenWrt install description Mediawiki page as an option for easier migration once we have confirmation.

1 Like

That is fantastic! Thank you very much! I look forward to using both sometime this week when I upgrade from:
OpenWrt SNAPSHOT r7301

I'll update will the results.

After using the above scripts for several upgrades now, I can confirm that they work great!
I use the second 'one liner' script provided by @alexmow after each upgrade and it cuts package reinstallation down to seconds.
Thank you to all who contributed!

@alexmow Let me see if I understand correctly how to use this script:

  1. (Optional, but strongly recommended) Always back up your configuration before re-flashing. Just use the LuCI web interface to Generate Archive

  2. Sign into the router with SSH.

  3. Before updating firmware, run the script below.

    echo -n "opkg update ; opkg install ";install_time=$(opkg status kernel|awk '$1=="Installed-Time:" {print $2}');opkg status|awk '$1=="Package:" {package=$2} $1=="Status:" {user_inst=/ user/ &amp;&amp; / installed/} $1=="Installed-Time:" &amp;&amp; $2!='$install_time' &amp;&amp; user_inst {print package}'|sort|sed ':a;N;$!ba;s/\n/ /g'

    This outputs a long line with opkg update ; opkg install user-installed-package-1 user-installed-package-2 user-installed-package-3 etc...

  4. Save that output text (keep the ssh window open, or save the text in a file on your laptop) for use in Step 5.

  5. Flash the new firmware.

  6. SSH into the router again. Paste the saved text into the command line. This restores all the packages that were previously installed in the router.

Correct? Thanks.

Correct. As an example here is my upgrade procedure:
SSH in and run the script. It will give an output of:
opkg update ; opkg install user installed package 1 user installed package 2 user installed package 3 etc...
Then copy the single line output and save. I also, generate a backup in LuCI and store in the same folder as the script output.
After I have upgraded I use SSH to manually install LuCI with: opkg update and opkg install luci-ssl
Then I copy and run the script output (package list) minus the opkg update ; to reinstall all my packages.
Lastly I log into LuCI, set my password and check that everything installed correctly. Then I'll either restore my configuration from backup or reconfigure from scratch (preferred).

Hope this helps!