6

I just took frustratingly long to find out that the binary for the "gnome-console" package is called "kgx".

Hence, my question:

Assuming that I know the name of an installed package from pacman, is there a general way to find the name of its binary that can be used to launch the application?

For context:

I knew that my default Arch GNOME installation provided a terminal emulator from the GUI. In the GUI, it was named "Console". So I queried pacman via pacman -Qs console. Which returned:

local/gnome-console 47.1-1 (gnome)
    A simple user-friendly terminal emulator for the GNOME desktop

However, gnome-console was not within the known namespace of my terminal. Hence, I knew that the actual binary must have a different name. At this point, my knowledge ended, and I had to search the internet (for somehow way too long) until I stumbled over an old comment on Reddit mentioning that the binary is actually called "kgx" instead.

I assume there is a better way to do this than hope that somebody on the internet knows the name of the binary that you are looking for.

1 Answer 1

7

You can, but it isn't quite as straightforward as you assume. A package isn't guaranteed to provide exacty one executable. Indeed, many provide multiple executable programs. For an obvious example, consider coreutils which provides basic GNU utilities like cat, chmod, ln, split and so on. So there is no "its binary" when talking about packages. Instead, you can get a list of the various binaries a package may provide.

Pedantic note delivered, let's see how to actually do it. I would just look for files included in the package that are installed in the various bin directories. Something like:

$ pacman -Ql gnome-console | awk '($2~/bin\/./){print $2}'
/usr/bin/kgx

The command pacman -Ql PACKAGE_NAME prints out the list of files and directories the package will touch, with the package in the first field, and the file/dir as the second:

$ pacman -Ql gnome-console | head
gnome-console /usr/
gnome-console /usr/bin/
gnome-console /usr/bin/kgx
gnome-console /usr/share/
gnome-console /usr/share/applications/
gnome-console /usr/share/applications/org.gnome.Console.desktop
gnome-console /usr/share/dbus-1/
gnome-console /usr/share/dbus-1/services/
gnome-console /usr/share/dbus-1/services/org.gnome.Console.service
gnome-console /usr/share/glib-2.0/

So we pass that through an awk command that prints the 2nd field if the 2nd field matches bin/ followed by at least one more character. This is to avoid printing out /usr/bin itself. Note that this assumes no spaces in any of the paths, which really should be a safe assumption here, but for the sake of completeness, here's one that can also deal with spaces (not in the package name as that isn't allowed):

$ pacman -Ql gnome-console | perl -ne 'print if s|^\S+\s(.*bin/.+)|$1|'
/usr/bin/kgx

And, just to illustrate the point in the first paragraph:

$ pacman -Ql coreutils | perl -ne 'print if s|^\S+\s(.*bin/.+)|$1|'
/usr/bin/[
/usr/bin/b2sum
/usr/bin/base32
/usr/bin/base64
/usr/bin/basename
/usr/bin/basenc
/usr/bin/cat
/usr/bin/chcon
/usr/bin/chgrp
/usr/bin/chmod
/usr/bin/chown
/usr/bin/chroot
/usr/bin/cksum
/usr/bin/comm
/usr/bin/cp
/usr/bin/csplit
/usr/bin/cut
/usr/bin/date
/usr/bin/dd
/usr/bin/df
/usr/bin/dir
/usr/bin/dircolors
/usr/bin/dirname
/usr/bin/du
/usr/bin/echo
/usr/bin/env
/usr/bin/expand
/usr/bin/expr
/usr/bin/factor
/usr/bin/false
/usr/bin/fmt
/usr/bin/fold
/usr/bin/head
/usr/bin/hostid
/usr/bin/id
/usr/bin/install
/usr/bin/join
/usr/bin/link
/usr/bin/ln
/usr/bin/logname
/usr/bin/ls
/usr/bin/md5sum
/usr/bin/mkdir
/usr/bin/mkfifo
/usr/bin/mknod
/usr/bin/mktemp
/usr/bin/mv
/usr/bin/nice
/usr/bin/nl
/usr/bin/nohup
/usr/bin/nproc
/usr/bin/numfmt
/usr/bin/od
/usr/bin/paste
/usr/bin/pathchk
/usr/bin/pinky
/usr/bin/pr
/usr/bin/printenv
/usr/bin/printf
/usr/bin/ptx
/usr/bin/pwd
/usr/bin/readlink
/usr/bin/realpath
/usr/bin/rm
/usr/bin/rmdir
/usr/bin/runcon
/usr/bin/seq
/usr/bin/sha1sum
/usr/bin/sha224sum
/usr/bin/sha256sum
/usr/bin/sha384sum
/usr/bin/sha512sum
/usr/bin/shred
/usr/bin/shuf
/usr/bin/sleep
/usr/bin/sort
/usr/bin/split
/usr/bin/stat
/usr/bin/stdbuf
/usr/bin/stty
/usr/bin/sum
/usr/bin/sync
/usr/bin/tac
/usr/bin/tail
/usr/bin/tee
/usr/bin/test
/usr/bin/timeout
/usr/bin/touch
/usr/bin/tr
/usr/bin/true
/usr/bin/truncate
/usr/bin/tsort
/usr/bin/tty
/usr/bin/uname
/usr/bin/unexpand
/usr/bin/uniq
/usr/bin/unlink
/usr/bin/users
/usr/bin/vdir
/usr/bin/wc
/usr/bin/who
/usr/bin/whoami
/usr/bin/yes

Alternatively, since it might be the case that some executable files are not installed in bin directories, you could iterate over the list of files and look for regular files that your user can execute:

$ pacman -Ql PACKAGE_NAME | cut -d ' ' -f2 | 
  xargs -I {} bash -c '[[ -x "{}" && -f "{}" ]] && echo "{}"'; 

In the case of coreutils, that includes one more file:

$ pacman -Ql coreutils | cut -d ' ' -f2 |
  xargs -I {} bash -c '[[ -x "{}" && -f "{}" ]] && echo "{}"'  | 
    grep -v bin
/usr/lib/coreutils/libstdbuf.so
2
  • 1
    Thank you for taking the time to offer so much context! Commented Oct 12, 2024 at 11:46
  • Perhaps using file on the pacman provided paths could provide more an exhaustive list in case of mischevious packets. Or not - no idea. Commented Oct 20, 2024 at 10:36

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.