8

I want to know the commands that a specific Debian package offers me.

For example lets say I installed a package called x.deb. This package surely contains some commands that i can use.

How to list these commands.

I know I can use compgen bash command to generate list of all available commands in my system but what i need is just for specific package.

I tried the solutions:

dpkg -L postgresql-9.3 | egrep '(bin|games)/'
/usr/lib/postgresql/9.3/bin/pg_upgrade
/usr/lib/postgresql/9.3/bin/pg_ctl
/usr/lib/postgresql/9.3/bin/pg_resetxlog
/usr/lib/postgresql/9.3/bin/postgres
/usr/lib/postgresql/9.3/bin/pg_xlogdump
/usr/lib/postgresql/9.3/bin/initdb
/usr/lib/postgresql/9.3/bin/pg_controldata
/usr/lib/postgresql/9.3/bin/postmaster

I tried the command postgres

user@userPc:~$ postgres
No command 'postgres' found, did you mean:
 Command 'postgrey' from package 'postgrey' (universe)
postgres: command not found
13

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...
  • There could be bin outside bin/ or games/. – Maythux Apr 1 '14 at 7:38
  • dpkg -L apache2 | egrep '(bin|games)/' No result. Please improve your answer – Maythux Apr 1 '14 at 7:39
  • @Hadi apache2 may be a bad example because that package is a metapackage that usually isn't even installed on systems running Apache. The command works - try coreutils: dpkg -L coreutils | egrep '(bin|games)/' – Martin von Wittich Apr 1 '14 at 7:56
  • 1
    +1, very nice. Just a couple of comments, you might want to use grep -Ew 'bin|sbin|games' instead, egrep is deprecated and you may as well search for sbin as well. Also, there is no reason to use a for loop here, using a while loop as I did in my answer instead, means you don't need to worry about IFS and word splitting. – terdon Apr 1 '14 at 15:25
  • 1
    From man grep: Direct invocation as either egrep or fgrep is deprecated, but is provided to allow historical applications that rely on them to run unmodified. Also, you regex, will match any directory that contains either games or bin which will include /usr/share/games/, and also foosbinaff and whatever else. – terdon Apr 1 '14 at 18:57
11

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.

  • Executables in /opt or /lib are not meant to be invoked by users, so you shouldn't list them. `apt-file -F list $package | grep -E '^(/usr)/(s?bin|games)/' gives you the list, with one exception: alternatives. – Gilles Apr 1 '14 at 22:35
  • @Gilles I don't see why not, the OP asked for commands, whether these were meant to be run manually or not is besides the point. Also, there are perfectly good reasons to use some of them, for example /lib/udev/findkeyboards can be very useful when writing keyboard udev rules. – terdon Apr 2 '14 at 15:20
  • /lib/udev/rule_generator.functions can be useful too. If you start listing everything that's useful, then it's not just executables you need to list, but any kind of code library. – Gilles Apr 2 '14 at 15:26
2

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.

0
  1. Normally, *bin/ are the most common places to have all programs placed. Even using a link. So there is very little chance that you need to concern commands outside *bin/.
  2. If you have not installed apache2, dpkg -L surely won't give you result. Please try apt-file tool (you need to install it).
  3. The name apache2 is a metapackage, it does not contain any programs.

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.