Terminal cheat sheet
Here's a small reference for working with postmarketOS/Alpine Linux.
Package management
The package manager in postmarketOS is called apk
, the Alpine Package Keeper. The list of packages can be found at pkgs.alpinelinux.org and pkgs.postmarketos.org.
The Alpine Linux wiki has a page comparing apk to other popular package managers, with many helpful examples.
Installing a package
$ sudo apk add neovim
Uninstalling a package
$ sudo apk del neovim
Upgrading the system
The -a
option allows downgrading packages to what's available in the repository. It is generally recommended to always use this option, especially on stable releases, to ensure that any package reverts make it to your device.
$ sudo apk upgrade -a
Repairing packages
Run various package repair strategies, e.g. running failed installation scripts again:
$ sudo apk fix
$ sudo apk fix name-of-package # will also reinstall name-of-package
Listing installed packages
Listing installed package versions (add | grep package-name
to filter for a specific package):
$ apk info -vv
$ apk info -vv | grep package-name
Installing build dependencies
$ sudo apk add build-base install-makedepends
$ install-makedepends neovim
Config files
The repositories are stored in /etc/apk/repositories
as one repository url per line. There's also /etc/apk/world
which is a list of packages that are explicitly installed. It's possible to add/remove packages from this list and then running apk fix
to apply those changes.
New installations of postmarketOS let apk ask for confirmation by default. If you don't want this, delete /etc/apk/interactive
(
pmaports!3444).
Logging with apk
A feature to log each apk action, especially which packages have been installed with an upgrade will be available in apk3. In the meantime, similar functionality can be achieved by installing etckeeper
. It turns your /etc
directory into a git repository, tracking changes to all files in there, and it also records package changes and related versions in the git log.
$ sudo apk add etckeeper
$ sudo apk add hello-world
$ sudo git -C /etc log
commit e8dc072cbe037eeaeec3adb8649680b2fcd10130 (HEAD -> master)
Author: root <root@nokia-n900>
Date: Tue Jan 9 15:43:28 2024 +0000
committing changes in /etc after apk run
Package changes:
+hello-world-1-r6
Service management
The service manager in postmarketOS is OpenRC. The basic service management is done with the familiar rc-service
command.
Tip: rc-service is also symlinked to service which is shorter to type. |
$ rc-service networkmanager status
$ sudo rc-service networkmanager start
$ sudo rc-service networkmanager stop
$ sudo rc-service networkmanager restart
To enable or disable services on boot you use the rc-update
command.
List the services that are added to a runlevel
$ rc-update
bootmisc | boot
chronyd | default
dbus | default
devfs | sysinit
dmesg | sysinit
gdm | default
haveged | default
hostname | boot
hwclock | boot
killprocs | shutdown
Start NetworkManager on boot (in the default runlevel)
$ sudo rc-update add networkmanager default
Stop NetworkManager starting on boot
$ sudo rc-update del networkmanager default
Log files
By default postmarketOS uses the busybox logging daemon for the syslog and it's configured to log to memory only. The logread
command is used to read the in-memory log. Writing standard output and standard error of a system service to the filesystem can be achieved by setting output_log
and error_log
to file paths in its service script, as described in the manual page openrc-run
.
ModemManager logs to syslog by default as well, but prints almost nothing until manually increasing the log level with sudo mmcli -G DEBUG
. Be aware that especially ModemManager logs a lot of sensitive information, such as phone numbers, text messages, IMEI, cell towers, etc!
Most user interfaces use tinydm to start the session in postmarketOS, which logs to ~/.local/state/tinydm.log
.
A discussion to possibly change logging defaults is in pmaports#1574.
Man pages
Man pages are not installed by default and are seperate from the normal packages. The docs
package is a metapackage that will pull in all the documentation for the software you have installed. You can also install only the documentation you need by not installing the docs
package
but installing the specific documentation subpackage. For example for vim documentation you can install vim-doc
the mandoc package is the man page reader itself
the man-apropos adds the apropos manpage search tool
the man-pages package will add the pages for core software like chmod but also linux headers
the docs package is a metapackage that pulls in the -doc package for everything you install
$ sudo apk add -i mandoc mandoc-apropos man-pages docs
$ man nvim
Changing your shell
Since the pmos installations are based on busybox the default shell is ash
, which is comparable to sh
. There are multiple shells packaged in Alpine if you want something better:
pick your favorite shell
$ sudo apk add -i bash zsh fish dash yash oksh elvish
set your login shell
$ chsh -s /bin/zsh
some config distributions are packaged
$ sudo apk add -i grml-zsh-config oh-my-zsh
Getting session environment
When working on things like pipewire or other software that needs access to the user session, it can be frustrating to do over ssh. The following one-liner can be used to set up the environment
# Replace with your DE (phosh, sway, etc)
$ export TARGET="gnome-shell"
$ eval $(cat /proc/(pidof $TARGET)/environ | tr '\0' '\n' | grep -v '^TERM=' | awk '{ print "export \"" $0 "\"" }')
This can be installed in your ~/.bashrc
or ~/.zshrc
as follows:
yoinkenv () { TARGET=${1:-gnome-shell} echo "Yoinking environment from $APP" eval $(cat /proc/$(pidof $TARGET)/environ | tr '\0' '\n' | grep -v '^TERM=' | awk '{ print "export \"" $0 "\"" }') }
Note that in order to have ~/.bashrc
being sourced in a ssh session, you need something like the following in your ~/.bash_profile
:
if [ -f ~/.bashrc ]; then . ~/.bashrc fi
Pushing source changes to a target
For some development, it might be easiest to edit the source code on your laptop/PC but compile on the device. This can be made easy with a small one-liner you can run from your project checkout to sync changes to the device every time you save. You will need to create the target directory on the device manually.
while true; do inotifywait -e modify src/**; rsync --exclude-from=.gitignore -a . pmos:projects/$(basename "$PWD")/; done
Rsync will ignore all paths specified in the local .gitignore
.
This expects you to have a pmos
entry in your SSH config, see SSH#Config for more info.
See also
- pmaports#1574 Make logging consistent