A bit -q
uiet or a little -v
erbose, apk search
outputs a list of packages:
$ cat /etc/apk/repositories
#/media/cdrom/apks
http://dl-cdn.alpinelinux.org/alpine/v3.17/main
http://dl-cdn.alpinelinux.org/alpine/v3.17/community
http://dl-cdn.alpinelinux.org/alpine/edge/main
http://dl-cdn.alpinelinux.org/alpine/edge/community
#http://dl-cdn.alpinelinux.org/alpine/edge/testing
$ apk search "hack" | tee /dev/tty | wc -l
s6-2.11.3.2-r2
font-hack-3.003-r4
rust-1.71.1-r0
py3-subtesthack-0.2.0-r1
rust-1.64.0-r2
py3-setuptools-65.6.0-r0
daemontools-encore-1.11-r1
nethack-3.6.7-r0
py3-setuptools-68.0.0-r2
nethack-doc-3.6.7-r0
zfs-2.1.12-r0
font-hack-nerd-3.0.2-r0
py3-subtesthack-pyc-0.2.0-r1
13
$ alias 1="grep rust | head -1"
$ apk search hack | 1 # rust-1.71.1-r0
$ apk -v search hack | 1 # rust-1.71.1-r0 - Rust Programming Language toolchain
$ apk search hack -q | 1 # rust
There are lines without hack
pattern in them. Why is that so? That's because apk search
acts as a fancy grep
over all fileds inside any APKINDEX
file it could find locally. Here, p:
means "provide" and D:
means "depend". Highlighted line below reveals why rust
package occured:
$ cd /var/cache/apk; ls -al
total 4404
drwxr-xr-x 2 root root 120 Aug 9 14:02 .
drwxr-xr-x 4 root root 80 Aug 9 13:58 ..
-rw-r--r-- 1 root root 1931593 Aug 9 14:02 APKINDEX.00163840.tar.gz
-rw-r--r-- 1 root root 450822 Aug 9 14:02 APKINDEX.066df28d.tar.gz
-rw-r--r-- 1 root root 656681 Aug 9 14:02 APKINDEX.85fe5889.tar.gz
-rw-r--r-- 1 root root 1460358 Aug 9 14:02 APKINDEX.b53994b4.tar.gz
$ tar -tOf *8d.tar.gz APKINDEX | grep -A13 -B1 "P:rust$"
C:Q1rOk4rSUpgkNoVpOxw2ARm4r17hw=
P:rust
V:1.71.1-r0
A:x86_64
S:193547354
I:622071808
T:Rust Programming Language toolchain
U:https://www.rust-lang.org/
L:Apache-2.0 AND MIT
o:rust
m:Jakub Panek <me@panekj.dev>
t:1691158261
c:70ce61bc0ba394fc0d0680f5ca9e7046b509fea6
D:gcc\
musl-dev\
so:libLLVM-16.so\
so:libc.musl-x86_64.so.1\
so:libgcc_s.so.1\
so:libscudo.so\
so:libstdc++.so.6
p:rust-bootstrap=1.71.1-r0\
rust-stdlib=1.71.1-r0\
so:libchalk_derive-1d53ee804995e4d5.so=0\
so:libcstr-fdb59b5b50a9bd8c.so=0\
so:libderive_more-539f099960be45c2.so=0\
so:libdisplaydoc-e1eca0e134a3e6d0.so=0\
so:libicu_provider_macros-db448138b24cd12b.so=0\
so:libproc_macro_hack-2bd8753fce48ac00.so=0\
so:librustc_driver-c37f132b6bcd4969.so=0\
so:librustc_fluent_macro-ed05c935b195e10a.so=0\
so:librustc_macros-7a5803295784a1d4.so=0\
so:libserde_derive-3cf132afc55e3abd.so=0\
so:libstd-09049943ce26e8ad.so=0\
so:libtest-845ed5882612fa58.so=0\
so:libthiserror_impl-f50746f2c83eae43.so=0\
so:libtracing_attributes-9a7955890e4dca11.so=0\
so:libunic_langid_macros_impl-4cf8b1b36598ab3f.so=0\
so:libyoke_derive-164b4353d24f8c22.so=0\
so:libzerofrom_derive-2ed30916df0ab153.so=0\
so:libzerovec_derive-62b78484466b6427.so=0\
cmd:rustc=1.71.1-r0\
cmd:rustdoc=1.71.1-r0
By deafult, search is way relaxed. It globs your query and scans the fields. Tight it with --exact
:
$ alias N="wc -l"
## `--exact`, `-x`, `-e` are all the same
$ apk search rust | N # 39
$ apk search '*rust*' | N # 39
$ apk search --exact rust | N # 1
$ apk search -x 'rust*' | N # 19
$ apk search -e '*rust' | N # 7
$ apk search '*rust*' -e | N # 39
## Note that this one takes no look at any `p:` or `D:` fields
$ apk search -v | grep rust | head -7
rustfmt-1.71.1-r0 - Rust Code Formatter
rust-gdb-1.71.1-r0 - GDB pretty printers for Rust
rust-1.71.1-r0 - Rust Programming Language toolchain
p11-kit-trust-0.25.0-r0 - System trust module from p11-kit
rust-1.64.0-r2 - The Rust Programming Language
libtpms-0.9.6-r0 - library providing software emulation of a Trusted Platform Module (TPM 1.2 and TPM 2.0)
monkeysphere-0.44-r1 - openpgp web of trust certification tools for SSH and TLS servers
## Grepping over name and description still does a good job
$ apk search -v | grep "text editor" | head -5
nano-doc-7.2-r1 - Enhanced clone of the Pico text editor (documentation)
gedit-doc-44.2-r3 - gedit is the GNOME text editor (documentation)
pluma-1.26.0-r5 - A small and lightweight UTF-8 text editor for the MATE
ed-1.19-r1 - Line-oriented text editor used to create, display, modify and otherwise manipulate text files
tau-0.12.0-r0 - GTK frontend for the Xi text editor, written in Rust
So the rule. Search becomes simpler with -eq
. Here is some examples:
$ apk search rust -eq # Just toolchain
$ apk search '*-doc' -eq # List all available docs
$ apk search 'ip*-doc' '*wm*-doc' -ev # Many at once
$ apk search '*-dev' -eq | grep curses # Is there curses?
$ apk search '*-libs' -ev | grep http # Any networking libraries?
## Another useful suffixes:
# - *-openrc
# - *-lang
# - *-completion
# - *-pyc
# - *-static
Next. What if you do not know the name of a package but know the name of a tool you need? Tighten thing using cmd:
.
$ apk search cmd:vim | N # 5; what packages own executable
$ apk search 'cmd:vim*' | N # 5; same as above
$ apk search 'cmd:*vim*' | N # 7; not staring but containing `vim` in
$ apk search 'cmd:*vim*' -q | N # 7; same as above
$ apk search -eq cmd:vim # package with `vim` command inside - guaranteed!
gvim
Ok, but what actually matched with not exact query?
## Exact match; realxed would find also `cmd:ipython` or `cmd:iperf`
$ apk search -eq cmd:ip
iproute2-minimal
## `apk info pkg1 pkg2 .. pkgN` prints details of every `pkgX`; see `apk info -h`
$ apk info -v iproute2-minimal
iproute2-minimal: IP Routing Utilities (/sbin/ip only)
iproute2-minimal: https://wiki.linuxfoundation.org/networking/iproute2
iproute2-minimal: 644 KiB
## Let's combine; note that it's not exact match over `ip`
$ apk search cmd:ip -q | xargs apk info -P | grep -e ^cmd:ip -e provides: -e ^$ | head
iptstate-2.2.7-r0 provides:
cmd:iptstate=2.2.7-r0
iptables-1.8.8-r2 provides:
cmd:iptables-apply=1.8.8-r2
cmd:iptables-legacy-restore=1.8.8-r2
cmd:iptables-legacy-save=1.8.8-r2
## `-P` here stands for "provide": commands, libraries, pkg-config files and so on
$ apk info -P ripgrep libevent libevent-dev
ripgrep-13.0.0-r6 provides:
cmd:rg=13.0.0-r6
libevent-2.1.12-r7 provides:
so:libevent-2.1.so.7=7.0.1
so:libevent_core-2.1.so.7=7.0.1
so:libevent_extra-2.1.so.7=7.0.1
so:libevent_openssl-2.1.so.7=7.0.1
so:libevent_pthreads-2.1.so.7=7.0.1
libevent-dev-2.1.12-r7 provides:
pc:libevent=2.1.12-r7
pc:libevent_core=2.1.12-r7
pc:libevent_extra=2.1.12-r7
pc:libevent_openssl=2.1.12-r7
pc:libevent_pthreads=2.1.12-r7
cmd:event_rpcgen.py=2.1.12-r7
## `-R` stands for "require", i.e. dependencies
$ apk info -R iproute2 libevent libevent-dev
iproute2-6.0.0-r1 depends on:
iproute2-minimal
iproute2-tc
iproute2-ss
/bin/sh
so:libc.musl-x86_64.so.1
so:libcap.so.2
so:libmnl.so.0
libevent-2.1.12-r5 depends on:
so:libc.musl-x86_64.so.1
so:libcrypto.so.3
so:libssl.so.3
libevent-dev-2.1.12-r5 depends on:
python3
libevent=2.1.12-r5
pkgconfig
Need to know what packages use concrete binary or library?
## Print packages that use `wg-quick`; tiny `-r` means reverse search
$ apk search -eqr cmd:wg-quick
wireguard-tools
ifupdown-ng-wireguard-quick
## Again: this is what provides `libssl`...
$ apk search so:libssl
nss-3.92-r0
libssl3-3.0.10-r0
dovecot-2.3.20-r7
libssl1.1-1.1.1u-r1
## ...that is what use `libssl`...
$ apk search so:libssl | N
779
## ...provide pkg-config...
$ apk search 'pc:*curses'
ncurses-dev-6.4_p20230722-r0
notcurses-dev-3.0.9-r2
## ...and use Linux's netlink...
$ apk search -r so:libmnl | N
53
## ...number of packages depending on `musl`...
$ apk search -r musl | N
14145
## ...and total # of packages from available locally APKINDEXes.
$ apk search | N
23803
Key takeaways
- Use exact match by default:
apk search -eq
- Use
cmd:
,so:
,pc:
prefixes - Use
-doc
,-dev
,-openrc
suffixes - Find out what non exact match returns with
| xargs apk info -P
- Don't hesitate and grep over
apk search -v
## Bonus
$ apk info # installed packages
$ apk info zsh bash fish # default to -dws (description, webpage, size)
$ apk info -a zsh bash fish # all fields, but... for installed packages
$ apk info -v 'libre*' # -dws in greppable format; `-v` verbose, remember?
$ apk info -W `which lbu` # who owns this path, package must be installed
$ apk info -L musl-dev # list of files installed by the package
$ apk info -r musl # what depend on it in the system's `/etc/apk/world`
$ apk list -I # same as `apk info`
$ apk stats # just run it ;)
$ apk version -I # all `APKINDEX`es yo have
$ apk version # things you have no up-to-date...
$ apk upgrade # ...so upgrade it
$ apk audit # see diversions from packages defaults