List all commands of a specific Debian package
Use dpkg -L pkgname
and pipe it to a grep command searching for bin/
and games/
:
$ dpkg -L bash | grep -E '(bin|games)/'
/bin/bash
/usr/bin/bashbug
/usr/bin/clear_console
/bin/rbash
If you want to check for all binaries regardless if they are in your $PATH
try this bash function:
find_binaries (){
dpkg -L "$@" | while read; do
[ -f "$REPLY" -a -x "$REPLY" ] && echo "$REPLY"
done
}
Invoke like so:
$ find_binaries postfix
...SNIP...
/usr/lib/postfix/postfix-files
/usr/lib/postfix/pipe
/usr/lib/postfix/proxymap
/usr/lib/postfix/local
/usr/lib/postfix/discard
...SNIP...
1. Use a tool designed for the job.
The easiest and probably the most robust way is to install dlocate
:
sudo apt-get install dlocate
You can then run
dlocate -lsbin package-name
As explained in man dlocate
:
-lsbin List full path/filenames of executable files (if any) in package
2. Parse the package database
This is a similar approach to @Winny's but simplified
apt-file -F list package | cut -d ' ' -f 2 |
while read file; do [[ -x $file && -f $file ]] && echo "$file"; done
If you don't have apt-file
installed, you can install and set it up with these commands:
sudo apt-get install apt-file
sudo apt-file update
The command above uses apt-file
to list a package's contents and then bash's tests -f
(is this a file?) and -x
(is it executable?) and prints the file's name if both tests are passed.
Note that while something like the command below will get you most executables:
apt-file -L list package | grep -Ew 'bin|sbin'
it will not find all because you also get executables in places like /opt
or even /lib
(various udev
tools for example). So, while using the -w
to match whole words increases your chances of identifying the files correctly, parsing the path is not a good approach and you should use one of the methods above instead.
If you have dlocate
installed, there's an easy way to list all the commands in an installed package:
dlocate -lsbin PACKAGE-NAME
With just dpkg
, you can list the files in the standard PATH directories (they're almost all executable programs, with very few exceptions):
dpkg -L PACKAGE-NAME… | sed -n 's!^\(/s\?bin\|/usr/s\?bin\|/usr/games\)/!!p' | sort -u
The exceptions are a couple directories — as of Debian wheezy, just two: /usr/bin/mh
and /usr/bin/nu-mh
.
If the package isn't installed, replace dpkg -L
by apt-file -F list
:
apt-file -F list PACKAGE-NAME… | sed -n 's!^\(/s\?bin\|/usr/s\?bin\|/usr/games\)/!!p' | sort -u
While there are executable files in other directories, they are not meant to be executed directly, which makes them irrelevant here.
These methods all miss a set of programs: those that are provided through the alternatives mechanism. For example, for the ftp
package, only netkit-ftp
and pftp
are provided, but this package actually provides the ftp
command, because /usr/bin/ftp
is a symbolic link to /etc/alternatives/ftp
which is a symbolic link to one of the ftp
implementations on the system, potentially /usr/bin/netkit-ftp
. The following command (which isn't an example of good programming, just a big one-liner) lists the commands provided by a package via the alternatives mechanism, as currently configured.
perl -lwe 'foreach (`dpkg -L @ARGV`) {chomp; ++$p{$_}} foreach (</bin/* /sbin/* /usr/bin/* /usr/sbin/*>) {$e = readlink; next unless defined $e and $e =~ m!^/etc/alternatives/!; $t = readlink $e; print if $p{$t}}' PACKAGE_NAME…
If you want to list the commands that could be provided via an alternative which is currently configured to point to a different package, you need to parse the files in /var/lib/dpkg/alternatives
.
Symbolic links and configuration files that implement the alternatives mechanisms are not registered in packages but registered automatically in postinst
, which makes it difficult (and in fact technically impossible if a package's installation script doesn't follow conventions) to query the alternatives provided by an uninstalled package.