linux/

PS1 with git status without any extra dependencies

In this guide, we will add git status to the command line prompt without any extra dependencies.

Our new prompt has the following additional functionality:

  • If the command exits with a non-zero status, it will show the exit code in red, e.g., ✘127.
  • The username and hostname are shown in green, e.g., user@hostname (should prevent the user from executing commands on the wrong host).
  • The current working directory is shown in blue.
  • The git status is shown in square brackets (only if inside a git repository):
    • The branch name is shown in yellow.
    • Untracked files are shown with a yellow question mark.
    • Staged files are shown with a green plus sign.
    • Unstaged files are shown with a red exclamation mark.
    • Ahead and behind of upstream are shown with up and down arrows, respectively.
  • The prompt is split into multiple lines for better readability.

Open your ~/.bashrc file and add the following snippet:

function git_status_prompt() {
    local git_info=""
    if git rev-parse --is-inside-work-tree &>/dev/null; then
        # Define colors
        local branch_color="\033[0;33m"     # Yellow for branch name
        local reset_color="\033[0m"         # Reset to default color
        local untracked_color="\033[1;33m"  # Bold yellow for untracked
        local staged_color="\033[1;32m"     # Bold green for staged
        local unstaged_color="\033[1;31m"   # Bold red for unstaged

        # Show branch name if on a branch, otherwise show commit hash
        local branch_name=$(git symbolic-ref --short -q HEAD 2>/dev/null)
        if [[ -n "$branch_name" ]]; then
            git_info+="[${branch_color}${branch_name}${reset_color}"
        else
            git_info+="[${branch_color}@$(git rev-parse --short HEAD)${reset_color}"
        fi

        # Add additional status indicators with respective colors
        [[ -n $(git ls-files --others --exclude-standard) ]] && git_info+=" ${untracked_color}?${reset_color}"
        ! git diff --cached --quiet && git_info+=" ${staged_color}+${reset_color}"
        ! git diff --quiet && git_info+=" ${unstaged_color}!${reset_color}"

        # Ahead/behind of upstream
        local ahead=$(git rev-list --count @{u}..HEAD 2>/dev/null)
        local behind=$(git rev-list --count HEAD..@{u} 2>/dev/null)
        [[ $ahead -gt 0 ]] && git_info+=" ⇡$ahead"
        [[ $behind -gt 0 ]] && git_info+=" ⇣$behind"

        # Close the square bracket
        git_info+="]"
    fi
    echo -e "$git_info"
}
PS1='$(if [ $? -ne 0 ]; then echo "\[\e[0;31m\]✘$? \[\e[0m\] "; fi)\[\e[01;32m\]\u@\h\[\e[0m\] \[\e[01;34m\]\w\[\e[0m\] $(git_status_prompt)\n\$ '

Apply the changes by running:

source ~/.bashrc
| 3 Nov 2024

Remap the key between left shift and Z in Logitech MX Mechanical Mini in Linux

In Europe, Logitech only sells keyboards with ISO layout. This means that there is an additional key between the left shift and Z. This key is often in the way if you are used to the US layout (ANSI layout). Solaar does not allow you to remap this key.

  1. Install evtest:
sudo dnf install evtest
  1. Start it and find the device:
sudo evtest

evtest will output all available devices. For example:

No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:	Sleep Button
/dev/input/event1:	Power Button
...
/dev/input/event27:	solaar-keyboard
/dev/input/event3:	Logitech USB Receiver
/dev/input/event4:	Logitech USB Receiver Mouse
/dev/input/event5:	Logitech USB Receiver Consumer Control
/dev/input/event6:	Logitech USB Receiver System Control

The keyboard is solaar-keyboard. However, it is connected via the USB receiver. This means that the device is /dev/input/event3.

  1. Record the key code by pressing the key:
Event: time 1692951945.797570, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70064
Event: time 1692951945.797570, type 1 (EV_KEY), code 86 (KEY_102ND), value 1

If you selected solaar-keyboard as the device, evtest won’t record any key

  1. Create a new rule:
sudo vim /etc/udev/hwdb.d/mx-keys.hwdb

Add the following content:

evdev:name:Logitech USB Receiver:*
  KEYBOARD_KEY_70064=leftshift
  1. Update the rules to test the new configuration:
sudo systemd-hwdb update
sudo udevadm trigger
| 20 May 2024

Upgrade to fedora 40

Make sure your current system is up to date:

sudo dnf upgrade --refresh

Reboot:

reboot

Install dnf plugin which updates OS:

sudo dnf install dnf-plugin-system-upgrade

Download and prepare packages for upgrade:

sudo dnf system-upgrade download --releasever=40

Reboot and start upgrade process

sudo dnf system-upgrade reboot
| 23 Apr 2024

Fix missing shortcuts in Logitech MX Mechanical Mini in Linux

Logitech MX Mechanical Mini keyboard works mostly great in Linux. However, there are few buttons which don’t: Mic mute, Screenshots, Emoji, Voice dictation. To fix it, install solaar and reboot your computer (important, otherwise the app will hang):

sudo dnf install solaar
reboot

Configuring every button is 2-step process.

On the first step, the button is marked as a custom button (Diverted):

On the second step, click Rule Editor in the bottom left corner and there you can assign a new action to it:

Solaar keeps configuration files in ~/.config/solaar/ directory. Rules are stored in ~/config/solaar/rules.yaml file:

%YAML 1.3
---
- Key: [MultiPlatform Search, pressed]
- KeyPress:
  - XF86_AudioNext
  - click
...
---
- Key: [Voice Dictation, pressed]
- Execute: [firefox, 'https://gemini.google.com']
...
---
- Key: [Snipping Tool, pressed]
- KeyPress:
  - Print
  - click
...
---
- Key: [Open Emoji Panel, pressed]
- Execute: gnome-characters
...
---
- Key: [Mute Microphone, pressed]
- KeyPress:
  - XF86_AudioMicMute
  - click
...

The configuration file is located in ~/.config/solaar/config.yaml and is unique for every keyboard. It contains the keyboard’s name, serial number and etc. Our modified configuration should look like this:

- 1.1.10
- _NAME: MX Mechanical Mini
  _absent: [hi-res-scroll, lowres-scroll-mode, hires-smooth-invert, hires-smooth-resolution, hires-scroll-mode, scroll-ratchet, smart-shift, thumb-scroll-invert,
    thumb-scroll-mode, onboard_profiles, report_rate, pointer_speed, dpi, speed-change, backlight-timed, reprogrammable-keys, persistent-remappable-keys,
    crown-smooth, divert-crown, divert-gkeys, m-key-leds, mr-key-led, gesture2-gestures, gesture2-divert, gesture2-params, sidetone, equalizer, adc_power_management]
  # <redacted>
  _sensitive: {divert-keys: true, multiplatform: false}
  # <redacted>
  backlight: true
  change-host: null
  disable-keyboard-keys: {1: false, 4: false, 8: false, 16: false}
  divert-keys: {212: 1, 226: 0, 227: 0, 231: 0, 232: 0, 233: 0, 259: 1, 264: 1, 266: 1, 267: 0, 268: 0, 269: 0, 270: 0, 271: 0, 272: 0, 273: 0, 274: 0,
    277: 0, 279: 0, 280: 0, 281: 0, 282: 0, 283: 0, 284: 1, 286: 0, 316: 0, 321: 0}
  fn-swap: false
  multiplatform: 0
| 26 Feb 2024

Monitor open connections

This command will plot open connections:

{ while true; do ss -ant | grep ESTAB | wc -l; sleep 0.1; done } | ttyplot
| 24 Feb 2024

dnf: list all dependencies of a package

dnf repoquery --deplist <package-name>
| 6 Nov 2023

How to use your old Android phone as a webcam

No matter how expensive your webcam is, it will never be as good as your old phone’s camera. In this guide, we will give a second life to your old phone by using it as a webcam. All software used in this guide is free.

Android phone

We will need to install the following software on your mobile phone:

  1. IP Camera to stream video from your phone’s camera to your desktop computer over WiFi.
  2. (Optional) droidVNC-NG VNC Server to control your phone remotely from your desktop computer.

Desktop computer

This guide is written for Fedora, but it should give you a general idea of how to set it up on other distributions.

We will need to install v4l2loopback to create a virtual camera device and ffmpeg to stream video from remote camera of the mobile phone to the virtual camera device.

v4l2loopback is a kernel module that allows you to create “virtual video devices”. It is available in rpmfusion repository.

  1. Enable rpmfusion repository:
sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
  1. Install dependencies:
sudo dnf install ffmpeg v4l2loopback akmod-v4l2loopback
  1. Verify that v4l2loopback is loaded:
lsmod | grep v4l2loopback
  1. If it is not loaded, run this command:
akmods --kernels $(uname -r) --rebuild
# Confirm that it was loaded
lsmod | grep v4l2loopback

Add the following helper function to your .bashrc file to start streaming from your phone:

webcam () {
  ffmpeg -i http://192.168.2."$1":4747/videofeed -vf format=yuv420p -f v4l2 /dev/video0
}

Assuming that your phone’s IP address is 192.168.2.38 and IP Camera is running on port 4747, you can start streaming by running webcam 38 in your terminal. I keep my phone’s IP assress dynamic as it changes once in a while, if I don’t use it for a long time.

Hardware setup

I have an old Google Pixel 3a phone which is mounted on the top of my monitor. The phone is attached to the mount with magnetic ring. At the time of writing, the setup cost me around 25 EUR:

How to use

  1. On mobile phone, start IP Camera and select “Start server” from the menu. In the bottom part of the screen, you will see the IP address and port number.
  2. On desktop, run the following command, providing the IP address of your phone and the port number:
ffmpeg -i http://192.168.2.26:4747/videofeed -vf format=yuv420p -f v4l2 /dev/video0
## or use the helper function
webcam 26

You can confgiure video resolution and other settings of your phone’s camera by navigating to http://192.168.2.26:4747/ in your browser.

If you install droidVNC-NG VNC Server, you can start IP Camera remotely from your desktop. This is useful if you want to start streaming from your phone without touching it. On the desktop computer, use Connections app (comes by default in GNOME) to connect to your phone.

Troubleshooting

If for some reason v4l2loopback module is not compiled correctly, you can compile it manually by following this instruction.

| 15 Oct 2023

Upgrade CentOS Stream 8 to CentOS Stream 9

  1. Update OS
dnf update -y
  1. Reboot system if there were any updates
reboot
  1. Disable CentOS 8-specific modules (they are blocking kernel updates)
dnf module disable python36 virt
  1. Install CentOS 9 repositories. All CentOS 9 packages are listed here
dnf install https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/Packages/centos-stream-release-9.0-22.el9.noarch.rpm https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/Packages/centos-gpg-keys-9.0-22.el9.noarch.rpm https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/Packages/centos-stream-repos-9.0-22.el9.noarch.rpm
  1. Run command to switch packages:
dnf --releasever=9 --allowerasing --setopt=deltarpm=false distro-sync -y
  1. Rebuild RPM database (this will chnage the backend to sqlite):
rpm --rebuilddb
  1. Disable subscription manager. Open file /etc/yum/pluginconf.d/subscription-manager.conf and set enabled to 0

  2. Reboot and verify

cat /etc/redhat-release
  1. Verify that the latest kernel is used (5.14+)
uname -a
  1. If not, use grubby to set the latest kernel as the default one, reboot the system and remove old kernels from CentOS 8:
# List all boot options
grubby --info=ALL

# Reflect the desired kernel in configuration
grubby --set-default vmlinuz-<version>.<arch>

# Make sure the index is also set in `/etc/default/grub` file

# Regenerate boot configuration
grub2-mkconfig -o /boot/grub2/grub.cfg

reboot

# Remove old kernels...

The instructions are inspired by CentOS 8 to CentOS Stream 8 migration guide and Fedora upgrade procedure

| 28 Aug 2023

How to use Android phone camera on desktop computer via WiFi with DroidCam

  1. Install DroidCam on your phone. There are free and paid versions. Paid version enables HD quality
  2. Install DroidCam in your desktop:
sudo dnf copr enable meeuw/droidcam
sudo dnf install droidcam
  1. Launch both mobile and desktop applications. Connect desktop client to your phone’s camera (IP address and port are displayed on your phone). Desktop client will connect to your camera via WiFi and create a virtual camera device.

If droidcam doesn’t start with the following error:

$ droidcam
Fatal: droidcam video device reported pixel format 34524742 (BGR4), expected 32315559 (YU12/I420)
Try 'v4l2loopback-ctl set-caps "video/x-raw, format=I420, width=640, height=480" /dev/video<N>'

Run this command:

v4l2loopback-ctl set-caps /dev/video "YU12:640x480"
| 2 Aug 2023

rygel: Disable inactivity timeout when streaming video

This script demonstrates how to disable system inactivity timeout in Gnome when running Rygel and restore it to the original value after exiting:

#!/bin/bash

# Save current inactivity timeout
TIMEOUT=$(gsettings get org.gnome.settings-daemon.plugins.power sleep-inactive-ac-timeout)
echo "Current timeout: $TIMEOUT"

# Execute commands on Ctrl + C
function ctrl_c() {
  echo "Exiting rygel..."
  gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-timeout $TIMEOUT
  echo "Inactivity timeout restored to $TIMEOUT. Bye!"
  sleep 2
}

# Set the trap for Ctrl+C
trap ctrl_c INT

# Disable the inactivity timeout
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-timeout 0

# Briefly start rygel to allow it to add new files
timeout 2s rygel

# Run command to fix filenames
rygel-titlefix

# Actually run rygel
rygel

| 17 Jul 2023