#!/bin/bash # # DESCRIPTION: # dmenu-based mount/unmount helper # [ -n "$DEBUG" ] && set -x export MENU_PROMPT="󰕓 mnts" # check requirements for app in awk jq lsblk notify-send; do if ! command -v "$app" >/dev/null; then printf "%s: %s not installed but required\n" "$(basename "$0")" "$app" >&2 exit 1 fi done exec= while getopts hx: o; do case "$o" in x) exec="$OPTARG" ;; h | ?) exit 2 ;; esac done shift $((OPTIND - 1)) # mount <1:mode> <2:device> <3:label> <4:path> mount() { local ok=0 local logfile=$(mktemp --tmpdir -t "mnts-${3}-XXXXX") local icon=/usr/share/icons/mdi/scalable/harddisk.svg trap '{ rm -f "$logfile"; }' EXIT case "$1" in mount) local path icon=/usr/share/icons/mdi/scalable/harddisk-plus.svg path="/media/$(tr '[:upper:]' '[:lower:]' <<<"$3")" [ ! -d "$path" ] && mkdir -p "$path" doas -n mount -v -o "uid=$(id -u),gid=$(id -g)" "$2" "$path" >"$logfile" 2>&1 if [ -n "${exec}" ]; then sh -c "$exec $path" & disown fi ;; unmount) icon=/usr/share/icons/mdi/scalable/harddisk-remove.svg doas -n umount -v "$2" >"$logfile" 2>&1 ;; esac if [ "$ok" -eq 0 ]; then notify-send -i "${icon}" -a mnts mnts "$(cat "${logfile}")" else notify-send -i "${icon}" -a mnts -u critical -t 30000 mnts "${1}ing ${3} [${2}] failed:\n$(cat "${logfile}")" fi } handle() { while read -r line; do dev=$(awk '{print $1}' <<<"$line") label=$(awk '{print $2}' <<<"$line") path=$(awk '{print $3}' <<<"$line") mode=$(awk '{if(length($3)<1) print "mount";else print "unmount";}' <<<"$line") [ -n "${DEBUG}" ] && printf 'DEBUG: mode:%s, dev:%s, path:%s\n' "${mode}" "${dev}" "${path}" mount "${mode}" "${dev}" "${label}" "${path}" & done } doas -n lsblk -flJ | jq -r '.blockdevices[] | select(.uuid?!="" and .name?) | select((.name | test("hibiki|luks|nvme|loop[0-9]+") | not)) | [("/dev/"+.name), .label, (.mountpoints[0] // "")] | @tsv' | column -s $'\t' -t | menu --list=8 | handle