Scripting Tips and Tricks

This is my collection of my tips and tricks for writing Bash or Dash scripts. These are what I understood after many years of using linux and writing the scripts.

Immediate Return

If Bash is waiting for a command to complete and receives a signal for which a trap has been set, it will not execute the trap until the command completes. If Bash is waiting for an asynchronous command via the wait builtin, and it receives a signal for which a trap has been set, the wait builtin will return immediately with an exit status greater than 128, immediately after which the shell executes the trap.
↳ https://www.gnu.org/software/bash/manual/html_node/Signals.html

mexii

It is simple but innovative and complicated logic. Movement is in new method by pressing Enter. The indicators in the prompt line, @ [0%]: shows the direction, @ is downward and # is upward. And 0 is movement lock off, LOCKED=0 and 1 is movement lock on, LOCKED=1. % is where input letter is to appear. In this script, the chain of variables acting like toggle and relative switches is the best.

Sway Per-window Keyboard Layout

In Sway, swaymsg -m is to monitor (watch) events. For example, swaymsg -m -t subscribe '["window"]' is to watch (monitor) window event in Sway. Sway (5), Sway-ipc (7) and swaymsg (1) man pages are to read.

Based on event monitoring of swaymsg -m -t subscribe '["window", "input"]', the following script was written to implement per-window keyboard layout in sway.

~
#!/bin/dash

if [ "$(id -u)" -eq 0 ]; then
    exit 0
fi
trap 'rm "$LOGFI"' EXIT
trap 'exit 0' INT
SCRIPTNAME="$(basename -- "$0")"
if pidof -x "$SCRIPTNAME" -o "$$"; then
    pkill -INT "$SCRIPTNAME"
    exit 0
fi
MSHTD=/tmp/minsoehan.msh.9.d
LOGFI="$MSHTD"/mswaykbd.log
KBID="1:1:AT_Translated_Set_2_keyboard"
mkdir -p "$MSHTD"
echo "0:0" > "$LOGFI"
swaymsg -m -t subscribe '["window", "input"]' | jq -r --unbuffered '
    if .change == "close" then
        "CLOSE:" + (.container.id | tostring)
    elif .change == "focus" then
        "FOCUS:" + (.container.id | tostring)
    elif .input.identifier == "'$KBID'" then
        "KBLCH:" + (.input.xkb_active_layout_index | tostring)
    else
        empty
    end' | while read -r EVENT; do
    TYPE=$(echo "$EVENT" | cut -d ':' -f 1)
    VALU=$(echo "$EVENT" | cut -d ':' -f 2)
    case $(echo "$EVENT" | cut -d ':' -f1) in
        "CLOSE")
            TODELE="$VALU"
            ;;
        "FOCUS")
            PREEVT=$(tail -n 2 "$LOGFI" | head -n 1)
            PRECTN=$(echo "$PREEVT" | cut -d ':' -f 1)
            if [ "$VALU" -eq "$PRECTN" ]; then
                PREKBL=$(echo "$PREEVT" | cut -d ':' -f 2)
            else
                PREKBL=$(grep ^"$VALU": "$LOGFI" | tail -n 1 | cut -d ':' -f 2)
            fi
            if [ -z "$PREKBL" ]; then
                PREKBL=0
            fi
            NOWKBL=$(swaymsg -t get_inputs | jq -r --arg id "$KBID" '.[] | select(.identifier == $id) | .xkb_active_layout_index')
            if [ "$PREKBL" -ne "$NOWKBL" ]; then
                swaymsg input type:keyboard xkb_switch_layout "$PREKBL"
            fi
            echo "${VALU}:${PREKBL}" >> "$LOGFI"
            if [ -n "$TODELE" ]; then
                sed -i "/^${TODELE}:/d" "$LOGFI"
                unset TODELE
            fi
            ;;
        "KBLCH")
            CTNID=$(swaymsg -t get_tree | jq -r '.. | try select(.focused == true) | .id')
            echo "${CTNID}:${VALU}" >> "$LOGFI"
            ;;
    esac
done

And the following script is to have keyboard layout id on the status bar:

mshstatus

For me, it took many years to understand trap and signal for immediate updating in status on a bar like swaybar. According to gnu bash manual, it can be understood that sleep [n] & and wait $! is key to implement mechanism of immediate trigger in status blocks. Importantly, wait $! must be right after sleep command with & for going into background, for example, sleep 9 &:

~
...
sleep 9 &
wait $!
...

Note: $! is process id (pid) of previous command.

AWK Basic

Awk is a programming language that can handle and manipulate data. Suppose we have the following data file.

datafile.txt
orange 22.5 0
banana 19.5 12
apple 23.0 0
mango 25.0 30
papaya 22.5 25

Print only certain field, first field for instance.

~
awk '{print $1}' datafile.txt

Print the lines (the whole line, $0) with value at third field is greater than 0.

~
awk '$3 > 0 {print $0}' datafile.txt

Do some maths (value at second field is multiplied by value at third field) and print.

လူနှင့် ပြတင်းပေါက်

ငယ်ငယ်က Windows XP ဆိုတာ အတော်ကြားခဲ့ရဖူးတာ မှတ်မိကြလိမ့်မည်။ တော်တော် လူကြိုက်များခဲ့ပုံ ဖြစ်သည်။ အဲ့သည့်နောက် Windows 7၊ ပြီးတော့ Windows 10။ သူတို့ကြားထဲ Windows Vista, Windows 8 ဆိုတာတွေလည်း ရှိခဲ့သည်။ သို့သော် လူကြိုက်များခဲ့ကြပုံမပေါ်။

Windows Version များ တစ်ခုပြီးတစ်ခု ခေတ်ကုန်သွားခဲ့သည်။ ယခု Window 10 လည်း ခေတ်ကုန်သွားခဲ့ပြီ။ Microsoft သည် Windows 10 ကို ၂၀၂၅ ခုနှစ်၊ အောက်တိုဘာလ ၁၄ ရက်နေ့မှစ၍ Support ရပ်လိုက်ပြီဖြစ်ကြောင်း ကြေငြာခဲ့သည်။

Windows 10 has reached the end of support on October 14, 2025. At this point technical assistance, feature updates and security updates is no longer provided. If you have devices running Windows 10, we recommend upgrading them to Windows 11, a more modern, secure, and highly efficient computing experience. If devices do not meet the technical requirements to run on Windows 11, we recommend that you enroll in the Windows 10​​​​​​​ Consumer Extended Security Updates (ESU) program or replace the device with one that supports Windows 11.
↳ Windows 10 support has ended on October 14, 2025

Progressive Web App (PWA)

Progressive Web Apps (PWAs) are web apps built and enhanced with modern APIs to deliver enhanced capabilities, reliability, and installability while reaching anyone, anywhere, on any device, all with a single codebase.

Reads

https://developers.google.com/codelabs/pwa-in-play#0
https://web.dev/learn/pwa/
https://github.com/GoogleChromeLabs/bubblewrap/tree/main/packages/cli https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps

Steps

  1. Make Website PWA Ready
  2. Build PWA using bubblewrap
  3. Signing the App

1. Make Website PWA Ready

Create /app.webmanifest file with the following content:

/app.webmanufest
{
  "name": "MGMAemp",
  "short_name": "MGMAemp",
  "start_url": "/",
  "scope": "/",
  "icons": [
    {
      "src": "/favicon/web-app-manifest-192x192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "maskable"
    },
    {
      "src": "/favicon/web-app-manifest-512x512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable"
    }
  ],
  "theme_color": "#ffffff",
  "background_color": "#ffffff",
  "display": "standalone"
}

Suggestion Online favicon generators like https://realfavicongenerator.net/ generates not only favicons, but also site.webmanifest file with PWA basic content:

Image Processing for Website

Image processing became essential part of web development nowadays. It is my way of image processing in Arch Linux with following steps:

  1. Resizing big image before optimizing using ImageMagic or FFmpeg
  2. Optimizing image using:
  3. Convert image to webp format using cwebp of libwebp

Install Required Software in Arch Linux

~
pacman -S jpegoptim pngquant libwebp libwebp-utils

Resize Image

Using ImageMagic

Astro Notes

JSON import type errors

When we do:

index.astro
import mpps from "../../../content/members/documents/pps-myan/pps-myan.json";
import epps from "../../../content/members/documents/pps-eng/pps-eng.json";

VSCode/TS will show red underlines because:

  • By default, TypeScript doesn’t always know how to type *.json imports.
  • Unless you have "resolveJsonModule": true in your tsconfig.json, VSCode/TS will complain (red underline), even though Astro’s bundler (Vite) will run it fine.

Fix:

tsconfig.json
{
  "compilerOptions": {
    "resolveJsonModule": true,
    "esModuleInterop": true
  }
}

Combining Layouts, Astro and Md

You may want unify them into a single layout by detecting whether the props come from *.astro, an astro page or *.md, a Markdown/MDX page.