[Solved] How to check if a package is installed?

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Locked
1000
Level 5
Level 5
Posts: 999
Joined: Wed Jul 29, 2020 2:14 am

[Solved] How to check if a package is installed?

Post by 1000 »

Once I uninstalled some packages to slim down my own system.
Today I would like to check if the packages are still installed on the system.

For example:

Code: Select all

LIST="bluez
bluez-obexd
bluez-tools
avahi-autoipd
avahi-daemon
avahi-utils
libnss-mdns
ghostscript
ghostscript-x
printer-driver-pnm2ppa
printer-driver-ptouch
printer-driver-sag-gdi"
But I have problem with commands.

1. avahi-utils

Code: Select all

$ dpkg-query -W avahi-utils
avahi-utils	
But inside Synaptic package manager avahi-utils I have uninstalled.

Code: Select all

$ dpkg -l avahi-utils
Choice: U = Unknown / I = Install / R = Remove / P = Clean / H = Stop
| Condition: N = None / I = Installed / C = Configured / U = Unpacked /
| / F = part configured / H = part installed / W = trigger check./T=rev. payment
|| Errors? = (None) / R-do Mon inst. (capital letters in "Status" and "Errors" = problems)
|| / Name Version Architecture Description
+++ - ============== - ============ - ============ - ===== ============================
un avahi-utils <none> <none> (no description available) 

2. printer-driver-ptouch

Code: Select all

$ dpkg -l printer-driver-ptouch
dpkg-query: no package matching the pattern printer-driver-ptouch was found 
The package is also not installed in Synaptic package manager.


The messages are displayed correctly, but they are different.
and the error at the output is also different.
For example, from this packages only bash is installed:

Code: Select all

$ dpkg -l "bash" >/dev/null 2>&1 ; echo $?
0

$ dpkg -l "avahi-utils" >/dev/null 2>&1 ; echo $?
0

$ dpkg -l "printer-driver-ptouch" >/dev/null 2>&1 ; echo $?
1
I wanted to ask if there is any other tool?
Last edited by LockBot on Wed Dec 28, 2022 7:16 am, edited 2 times in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
1000
Level 5
Level 5
Posts: 999
Joined: Wed Jul 29, 2020 2:14 am

Re: How to check if a package is installed?

Post by 1000 »

Probably I found way.
If I can not check installed package, maybe I can list all installed packages
and then check if exist on the list :mrgreen:

Code: Select all

#!/bin/bash


LIST="bluez
bluez-obexd
bluez-tools
avahi-autoipd
avahi-daemon
avahi-utils
libnss-mdns
ghostscript
ghostscript-x
printer-driver-pnm2ppa
printer-driver-ptouch
printer-driver-sag-gdi"


INSTALLED=$(apt list --installed | awk -F '/' '{print $1}' | sed '1d')

while read LINE ; do
	if $(grep -q "$LINE" <<< "$INSTALLED") ; then
		echo "Installed: $LINE"
	fi
done <<< "$LIST"
rene
Level 20
Level 20
Posts: 12240
Joined: Sun Mar 27, 2016 6:58 pm

Re: How to check if a package is installed?

Post by rene »

dpkg -W in fact printing only the name and not an installed version means it's not installed. You can also however provide an explicit format string. I.e., something like

Code: Select all

for PKG in $LIST; do
	dpkg-query -W -f '${Package}: ${db:Status-Status}\n' $PKG
done
t42
Level 11
Level 11
Posts: 3686
Joined: Mon Jan 20, 2014 6:48 pm

Re: How to check if a package is installed?

Post by t42 »

.
why not

Code: Select all

apt policy avahi-utils

avahi-utils:
  Installed: 0.7-4ubuntu7
  Candidate: 0.7-4ubuntu7
  Version table:
 *** 0.7-4ubuntu7 500
        500 http://ftp.icm.edu.pl/pub/Linux/ubuntu focal/main amd64 Packages
        100 /var/lib/dpkg/status
space is an arguments delimiter apt policy avahi-utils printer-driver-ptouch
-=t42=-
rene
Level 20
Level 20
Posts: 12240
Joined: Sun Mar 27, 2016 6:58 pm

Re: How to check if a package is installed?

Post by rene »

Functionally, <shrug>. Conceptually, dpkg and brethren deal with the machine-local package database, apt et al with the repository. A package being installed or not is a question at the level of former, so, well. Which by the way wouldn't be to say that dpkg(-query) would be a favourite of mine. Noticed from this answer for example that for unknown packages, dpkg-query with the above format string doesn't just say e.g. "foobar: not found" or some such but errors out. Seems fine here but generally, <sigh>.
1000
Level 5
Level 5
Posts: 999
Joined: Wed Jul 29, 2020 2:14 am

Re: [Solved] How to check if a package is installed?

Post by 1000 »

1. With "apt list --installed" + grep inside loop like above

Code: Select all

$ time bash linuxmint.blacklist0

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

 PACKAGE --> FOUND INSTALLED	:ARCHITECTURE 
ghostscript 	--> ghostscript  (amd64)
 

real	0m0.338s
user	0m0.312s
sys	0m0.044s
2. With

Code: Select all

LANG=en_us_8859_1 dpkg-query -W -f '${Package}: ${db:Status-Status}\n' "$LINE" | grep ' installed\| config-files'
Result of script:

Code: Select all

$ time bash linuxmint.blacklist0
libnss-mdns: config-files
ghostscript: installed
printer-driver-pnm2ppa: config-files
dpkg-query: no packages found matching printer-driver-ptouch
dpkg-query: no packages found matching printer-driver-sag-gdi

real	0m0.383s
user	0m0.325s
sys	0m0.076s
3. With

Code: Select all

LANG=en_us_8859_1 apt policy "$LINE" | grep -B1 "Installed: [z-Z0-9]"
Result of script:

Code: Select all

$ time bash linuxmint.blacklist0
ghostscript:
  Installed: 9.50~dfsg-5ubuntu4.2

real	0m1.052s
user	0m0.866s
sys	0m0.221s
I guess the "apt policy" must open a large compressed file, so time will be longer.
Or the grep command needs to process more data.

Thank you all for the suggestions :D
User avatar
Termy
Level 12
Level 12
Posts: 4254
Joined: Mon Sep 04, 2017 8:49 pm
Location: UK
Contact:

Re: [Solved] How to check if a package is installed?

Post by Termy »

I wrote lspkg(1) for just this purpose:

https://github.com/terminalforlife/Perl ... urce/lspkg

So you'd just run: lspkg avahi-utils

If you install it, view its man page for more information: man lspkg

Alternatively, you could run dpkg -l avahi-utils If the package was set to install and installed correctly, the line for that package will lead with ii (install ok installed). The reason you see un for some packages is because the packages were uninstalled.

Another program I wrote to help users see what was done, when, and by whom, as well as showing what is still installed, is apt-history(1):

https://github.com/terminalforlife/Perl ... pt-history

Again, if you install it, view it's man page for more information: man apt-history
Last edited by Termy on Thu Apr 07, 2022 12:26 pm, edited 1 time in total.
I'm also Terminalforlife on GitHub.
1000
Level 5
Level 5
Posts: 999
Joined: Wed Jul 29, 2020 2:14 am

Re: [Solved] How to check if a package is installed?

Post by 1000 »

Termy
My examples are not the best. But I just wanted to show you and other people that
" dpkg -l " and the error level works a little different than you can expect.

You expect
If the package was set to install and installed correctly, the line for that package will lead with ii (install ok installed). The reason you see un for some packages is because the packages were uninstalled.
Not always.
If you have removed the package. Configuration files may remain in the system.
Perhaps the developer did not know what status to give for such a package.
Therefore, I have given this above three solutions.

Code: Select all

"apt list --installed" + grep

LANG=en_us_8859_1 dpkg-query -W -f '${Package}: ${db:Status-Status}\n' "$LINE" | grep ' installed\| config-files'

LANG=en_us_8859_1 apt policy "$LINE" | grep -B1 "Installed: [z-Z0-9]"
First command is not literally.
- Example in terminal, where " bash " this is package name.

Code: Select all

$ apt list --installed | grep ^'bash/'

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

bash/focal-updates,now 5.0-6ubuntu1.1 amd64 [installed]
Commands include " LANG=en_us_8859_1 " to avoid language differences.
This means that without it, a command in a system in another language would not work properly
because the commands use specific words in English that can be translated in other systems.
In above 3 examples I gave a time how fast it works for me.
User avatar
Termy
Level 12
Level 12
Posts: 4254
Joined: Mon Sep 04, 2017 8:49 pm
Location: UK
Contact:

Re: [Solved] How to check if a package is installed?

Post by Termy »

1000 wrote: Wed Jun 09, 2021 4:58 am Not always.
If you have removed the package. Configuration files may remain in the system.
Perhaps the developer did not know what status to give for such a package.
What you quoted was correct, but as you point out, it was also incomplete. Those packages are then listed as rc (I think the full description is deinstall ok config-files), and of course aren't marked for installation nor can they then be correctly installed.

For more information, refer to dpkg-query(1)'s man page.

I like what you did with handling different locales, but what about those in GB? I might be missing something here, but not everyone in GB will care to keep around US locales. Would something like LC_ALL='C' be a better solution? Genuinely asking, because I know it's sometimes used with sort(1) and the like.
I'm also Terminalforlife on GitHub.
1000
Level 5
Level 5
Posts: 999
Joined: Wed Jul 29, 2020 2:14 am

Re: [Solved] How to check if a package is installed?

Post by 1000 »

Would something like LC_ALL='C' be a better solution?
I assumed that English and American are the same :mrgreen:
You're right. I can be wrong.

When I wanted to use LC_ALL='C' I just forgot about this and couldn't find it.
I couldn't choose the British language. The local language was always used.
I found somewhere on the internet LANG=en_us_8859_1 and working for me.
The explanation of how it works is at the very bottom.

LC_ALL=C It is recommended by " man sort "
*** WARNING *** The locale specified by the environment affects
sort order. Set LC_ALL=C to get the traditional sort order that
uses native byte values.
https://www.man7.org/linux/man-pages/man1/sort.1.html

Documentation is not very informative
Note: The variable LANGUAGE is ignored if the locale is set to ‘C’.
https://www.gnu.org/software/gettext/ma ... E-variable

===========================

What is C language.
When you paste in terminal command

Code: Select all

locale -a
You will see also C and POSIX language.
All systems provide a POSIX locale, also known as the C locale.
https://pubs.opengroup.org/onlinepubs/0 ... ocale.html

I am not sure this documentation is appropriate for Linux in this case.
Linux is UNIX based, but it can have exceptions.
The standards emerged from a project that began around 1985. Richard Stallman suggested the name POSIX to the IEEE instead of former IEEE-IX.
--> https://en.wikipedia.org/wiki/POSIX
For C-language programs, the POSIX locale shall be the default locale when thesetlocale()function is not called.
https://1lib.pl/book/3690429/311f7f?id= ... ret=311f7f

I don't know what they mean by " default language ".
- This could be the language on the system.
- This might be the default message used in the application.

===========================

Something interesting


In this link, she or he used strace command to debug
The strace command allows you to see what files are loaded.
https://www.inmotionhosting.com/support ... th-lc-all/

And if you use another language,

Code: Select all

$ strace cat file.not.exist  2>&1 | grep 'write\|open'
openat(AT_FDCWD, "/etc/ld.so.preload", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "file.not.exist", O_RDONLY) = -1 ENOENT (Message about missing file in your language )
write(2, "cat: ", 5cat: )                    = 5
write(2, "file.not.exist", 14file.not.exist)          = 14
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/your_language/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (Message about missing file in your language )
openat(AT_FDCWD, "/usr/share/locale-langpack/your_language/LC_MESSAGES/libc.mo", O_RDONLY) = 3
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
write(2, ": Message about missing file"..., 35: Message about missing file in your language ) = 35
write(2, "\n", 1
You will see that the "/usr/share/locale-langpack/your_language/LC_MESSAGES/libc.mo" file is loaded.
.mo files contain the text of the application in another language
https://wordpress.stackexchange.com/que ... tion-files

Example with LC_ALL=C

Code: Select all

$ LC_ALL=C strace cat file.not.exist  2>&1 | grep 'write\|open'
openat(AT_FDCWD, "/etc/ld.so.preload", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "file.not.exist", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "cat: ", 5cat: )                    = 5
write(2, "file.not.exist", 14file.not.exist)          = 14
write(2, ": No such file or directory", 27: No such file or directory) = 27
write(2, "\n", 1
Example with LANG=en_us_8859_1

Code: Select all

$ LC_ALL=LANG=en_us_8859_1 strace cat file.not.exist  2>&1 | grep 'write\|open'
openat(AT_FDCWD, "/etc/ld.so.preload", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/LANG=en_us_8859_1/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/locale/LANG=en/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "file.not.exist", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "cat: ", 5cat: )                    = 5
write(2, "file.not.exist", 14file.not.exist)          = 14
write(2, ": No such file or directory", 27: No such file or directory) = 27
write(2, "\n", 1
In this example you can see that command " cat trying find file "/usr/lib/locale/LANG=en_us_8859_1/LC_IDENTIFICATION",
but not found.

Conclusions:
If any commands will not work with LANG=en_us_8859_1
It means that not will work only for people which have this en_us_8859_1 installed.
Locked

Return to “Scripts & Bash”