Skip to content

Instantly share code, notes, and snippets.

@denis2glez
Last active January 23, 2022 17:59
Show Gist options
  • Save denis2glez/25f38c006f666c51b4d07ee64b01cd43 to your computer and use it in GitHub Desktop.
Save denis2glez/25f38c006f666c51b4d07ee64b01cd43 to your computer and use it in GitHub Desktop.
A collection of customizations gathered over time.

Arch Linux tweaks

A collection of customizations gathered over time. Several of them come from different parts of the great ArchWiki.

To keep an up-to-date list of explicitly installed packages

Create the hook /etc/pacman.d/hooks/pkg-list.hook

[Trigger]
Operation = Install
Operation = Remove
Type = Package
Target = *

[Action]
Description = Update lists of explicitly installed packages 
When = PostTransaction
Exec = /bin/sh -c '/usr/bin/pacman -Qqen > /mnt/pkg/pkg_list.txt && /usr/bin/pacman -Qqem > /mnt/pkg/foreign_pkg_list.txt'

To install packages from a previously saved list of packages

While not reinstalling previously installed packages that are already up-to-date, run

sudo pacman -S --needed - < /mnt/pkg/pkg_list.txt

If you want to make sure that the installed packages of your system exactly match the list

While removing all packages that are not in it

sudo pacman -Rsu $(comm -23 <(pacman -Qq | sort) <(sort /mnt/pkg/pkglist.txt))

Optionally install an AUR helper

For instance, yay is an AUR helper written in Go.

pacman -S --needed git base-devel
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

Check out the official documentation for details. To install AUR packages from a previously saved list

yay -S --needed - < /mnt/pkg/foreign_pkg_list.txt

Tracking your dotfiles with Git

It has the advantage that only requires Git and does not need the use of symlinks. In particular, if you use the bare repository and alias method as follows

git init --bare ~/.dotfiles
alias config='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
config config status.showUntrackedFiles no

To restore the configuration from a repository $repo use

git clone --bare --recursive $repo "$HOME/.dotfiles"

alias config='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'

config checkout
config submodule update --recursive --remote
config config --local status.showUntrackedFiles no

Autostart tmux with latest configuration

Using in conjunction with the tmux-continuum plugin, add to the tmux config

 ~/.tmux.conf
---
# Last saved environment is automatically restored when tmux is started
set -g @continuum-restore 'on'

and then define the following systemd service to start tmux for the specific user

/etc/systemd/system/tmux@.service
---
[Unit]
Description=Start tmux in detached session

[Service]
Type=forking
User=%I
ExecStart=/usr/bin/tmux new-session -s %u -d
ExecStop=/usr/bin/tmux kill-session -t %u

[Install]
WantedBy=multi-user.target

Data backup using rsync, systemd, udev and inotify

There are multiple ways and tools to perform backups. An old method that I still use is to do local backups to a dedicated external drive.

This is for learning purposes only, for regular use consider an app like Déjà Dup instead.

Note that you have to set some variables. Basically, I set up a udev rule to detect when I mount the specific drive, as follows

/etc/udev/rules.d/99-backup_drive_mounted.rules
---
KERNEL=="sd?1", SUBSYSTEM=="block", ATTRS{idVendor}=="XXXX", ATTRS{idProduct}=="YYYY", ACTION=="add", \
RUN+="/bin/systemctl --no-block start backup_drive_mounted@%k.service"

As can be seen, it uses the backup_drive_mounted@.service service defined as

/etc/systemd/system/backup_drive_mounted@.service
---
[Unit]
Description=Backup drive connected
BindsTo=dev-%i.device

[Service]
Type=simple
ExecStart=/usr/local/bin/backup_drive_mounted.sh %I

Which in turn calls the following backup_drive_mounted script that manages the general logic

/usr/local/bin/backup_drive_mounted
---
#!/bin/bash

DEVBASE=$1
DEVICE="/dev/${DEVBASE}"
M_USER=<YOU>
BUS_ADDRESS=unix:path=/run/user/1000/bus
sleep 1

# See if this drive is already mounted
MOUNT_POINT=$(/bin/mount | /bin/grep ${DEVICE} | /usr/bin/awk '{ print $3 }')

if [ -n ${MOUNT_POINT} ]; then
    # Send desktop notification to user
    sudo -u ${M_USER} DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=${BUS_ADDRESS} \
        notify-send "Device ${DEVICE} mounted at ${MOUNT_POINT}"
    if sudo -u ${M_USER} DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=${BUS_ADDRESS} \
        zenity --width=300 --height=150 --question --title "Backup drive connected!" --text "Do you want to backup your data now?"; then
        /home/${M_USER}/.local/bin/backup_sync &&
            sudo -u ${M_USER} DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=${BUS_ADDRESS} \
                notify-send "Backup task completed!"
    else
        sudo -u ${M_USER} DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=${BUS_ADDRESS} \
            notify-send "Backup task canceled!"
    fi
    exit 0
else
    # Not mounted, exit
    sudo -u ${M_USER} DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=${BUS_ADDRESS} \
        notify-send "Device ${DEVICE} not mounted!"
    exit 1
fi

and finally calls the script in charge of creating the actual backup

~/.local/bin/backup_sync
---
#!/bin/bash

if [ $# -eq 0 ]; then
    MOUNT_POINT="/run/media/<M_USER>/drive"
else
    MOUNT_POINT=$1
fi

if [ -n ${MOUNT_POINT} ]; then
    if
        zenity --width=300 --height=150 --question --title "Backup drive connected!" --text "Do you want to backup your data now?"
    then
        rsync -rvh \
            --delete \
            --archive \
            --sparse \
            --hard-links \
            --exclude={'Temp'} \
            /home/<M_USER>/ "${MOUNT_POINT}/#_BACKUP_#" >/tmp/backup_sync.log
        notify-send "Backup task completed!"
    else
        notify-send "Backup task canceled!"
    fi
    exit 0
else
    # Not mounted, exit
    notify-send "Backup device not mounted!"
    exit 1
fi

And that's it.


To config Bluetooth

  1. Install the bluez-utils package, providing the bluetoothctl utility.
  2. In order to be able to use audio equipment like bluetooth headphones or speakers, you need to install the additional pulseaudio-bluetooth package.
  3. Setting up auto connection
/etc/pulse/default.pa
---
### Automatically switch to newly-connected devices
load-module module-switch-on-connect
  1. Add the modules
/etc/pulse/system.pa
---
load-module module-bluetooth-policy
load-module module-bluetooth-discover
  1. Start/enable bluetooth.service.
  2. The newer implementation of the PulseAudio sound server uses timer-based audio scheduling instead of the traditional, interrupt-driven approach. To turn timer-based scheduling off add tsched=0 in /etc/pulse/default.pa
/etc/pulse/default.pa
---
### https://wiki.archlinux.org/index.php/PulseAudio/Troubleshooting#Glitches,_skips_or_cracklings
load-module module-udev-detect tsched=0

The generic Bluetooth driver is the btusb kernel module. Check whether that module is loaded. If it's not, then load the module.


To disable a USB device using udev (e.g. an integrated webcam)

  1. Use the lsusb command to list your USB devices.
  2. Check the ID (idVendor and idProduct) of the particular USB device.
  3. Finally add a new udev rule to remove the device as soon as it is detected
/etc/udev/rules.d/40-disable-internal-webcam.rules
---
ACTION=="add", ATTR{idVendor}=="yyyy", ATTR{idProduct}=="xxxx", RUN="/bin/sh -c 'echo 1 >/sys/\$devpath/remove'"

Persisting configuration changes in V4L2 (e.g. for an external webcam)

  1. Use the lsusb command to list your USB devices.
  2. Check the ID (idVendor and idProduct) of the particular USB device.
  3. Finally add a new udev rule to set a default setting (e.g. zoom)
/etc/udev/rules.d/99-logitech-default-zoom.rules
---
SUBSYSTEM=="video4linux", KERNEL=="video[0-9]*", ATTR{index}=="0", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="yyyy", RUN+="/usr/bin/v4l2-ctl -d $devnode --set-ctrl=zoom_absolute=170"

Adding a delay to the gdm.service allows to start GDM consistently.

To do this insert ExecPreStart=/bin/sleep 2 line into the gdm.service file, so it looks like

... more ...
[Service]
ExecStartPre=/bin/sleep 2
ExecStart=/usr/bin/gdm
... more ...

In order to prevent this change from being overwritten, create a pacman hook that will always insert the delay after a gdm package update. The following hook is installed in /etc/pacman.d/hooks/gdm.hook.

[Trigger]
Operation=Install
Operation=Upgrade
Type=Package
Target=gdm

[Action]
Description=Adds a small delay to /usr/lib/systemd/system/gdm.service to work around bug
Depends=coreutils
When=PostTransaction
Exec=/usr/bin/sed -i '/^\[Service\]/a ExecStartPre=\/bin\/sleep 2' /usr/lib/systemd/system/gdm.service

This has worked well.


Changes in /etc/sudoers

In /etc/sudoers uncomment the following line

%wheel ALL=(ALL) ALL

and add the following to config the editor for systemctl edit command

Defaults env_keep += "EDITOR=/usr/bin/nvim"

In order to use Kvantum theme engine for Materia

After install materia-gtk-theme, then install kvantum-theme-materia (and materia-kde?). Then

mkdir -p ~/.config/environment.d/
echo 'QT_STYLE_OVERRIDE=kvantum' > ~/.config/environment.d/qt.conf

If your F<num> keys do not work

This is probably because the kernel driver for the keyboard has defaulted to using the media keys and requiring you to use the Fn key to get to the F<num> keys. To change the behavior temporarily, append 0 to /sys/module/hid_apple/parameters/fnmode.

echo 0 | sudo tee /sys/module/hid_apple/parameters/fnmode

To make the change permanent, in /etc/modprobe.d/hid_apple.conf set

options hid_apple fnmode=0

To set kernel parameters persistently

GRUB loads the /boot/grub/grub.cfg configuration file each boot. To change settings, edit /etc/default/grub. For instance:

GRUB_DEFAULT='Advanced options for Arch Linux>Arch Linux, with Linux linux'
...
GRUB_CMDLINE_LINUX_DEFAULT="mem_sleep_default=deep"

Finally, regenerate the configuration file by running sudo grub-mkconfig -o /boot/grub/grub.cfg.

Remember that after installing or removing a kernel, you just need to re-run the above command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment