How to re-install over 100 packages with a single command

I'm looking to write a script that takes a .txt filename as an argument, reads the file line by line, and passes each line to the command opkg install <package name>

I've tried:

xargs -a file.txt -I{} -d'\n' opkg install
< file.txt tr '\n' '\0' | xargs -0 -I{} opkg install

and

< file.txt sed 's/"/"\\""/g;s/.*/"&"/' | xargs -E '' -I{} opkg install

but all throw various errors (due to the particular xargs installed in OpenWrt?)

Is there a way to do this? I have over 100 packages to install and I'd like to avoid running opkg install <package> 100 times manually.

You can issue it like this:

opkg install package1 package2 …
2 Likes

Thanks Peter

The text file is a list of over 100 packages. What I was trying to do was pass that list to opkg install in such a way that each package is output as a space delimited list.

Your suggestion helped me however. I ended up running cat PTI.txt | tr '\n' ' ' and then copy/pasting the space delimited out put from that as the argument.

Not quite as elegant as I had hoped to be, but still... works!

3 Likes

To answer your original question, just in case it's still useful:

while read line
do
   opkg install "$line"
done < file.txt

This second version also works but it spawns subshells. These are probably harmless for your application.

cat file.txt | while read line
do
   opkg install "$line"
done
1 Like

It is not good to run single command. Installing one-by-one lets to take decision in case of error.

The question is how to read file line by line in bash.

I don’t entirely agree, although I do see your point.

In this case, it sounds like the op is looking for a hands-off way of managing package installs. If that is true, the human intervention/decision process is likely moot unless the error conditions and resolutions are coded into the script.

Beyond that, the end of the install process will provide “collected errors” which will be a full list based on everything that happened in that singular run of opkg install. By contrast, it would be hard to read the errors from say 100 individual installation commands (if scripted) since it would be buried in tons of other lines of output in the scroll back buffer (which also needs to be deep or they get lost).

Therefore, unless a human operator is watching and running the individual install commands, there is little to no reason to run then individually, and it can actually be beneficial to run them in a single command.

why don't you build an image with imagebuilder locally or using building server with your predefined 100 packages and install that image directly? assuming you have the storage space for that.

otherwise the while read line is your best option.

You can install all packages in one command (no need for a script):

opkg install $(cat file.txt)

Also remember what @psherman said:

Beyond that, the end of the install process will provide “collected errors” which will be a full list based on everything that happened in that singular run of opkg install.

2 Likes

that's not necessary true because there is a limit to command buffer so you may not able to pass all package names in one shot. read line is safer if you have a long list, passing handful of package names will work indeed with you one-liner.

1 Like

Probably OT, but I figured I'd mention another tack. If your goal is to update your router firmware, then restore the packages and settings, consider the Attended Sysupgrade package

I just posted that page as a DRAFT - but I've been using the package for months without problem. Enjoy!

3 Likes

I know, there is a limit, but I don't know the number. Are 100 arguments too many?

Even if you have thousands of arguments it's still a one-liner:

cat file.txt | xargs opkg install

The modified one-liner with xargs covers all cases like your example with read line.

The disadvantage of the read line solution is: you're calling opkg for every argument.

I was reading the POSIX reference material and the limit for a line is 2048 octets including the terminating new line char. You could probably test the limit yourself but 2047 characters might be a good value to plan on. I don't think there is a standard limit of the number of words on the command line but each app might have limits.

Thanks for your clarification.

isn't better if you compile a version with all the packages you need? I mean, you can use Attended Sysupgrade to do that, but I don't know if it is the best option for you

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.