#!/bin/sh #description: dmenu for killall #usage: dmenu-killall is best suited for launching from a shortcut #example: dmenu-killall #a gui menu appears asking for which app to kill progname="$(expr "${0}" : '.*/\([^/]*\)')" #variables are impractical to save complex cmds because of shell expantion #therefore functions are required: http://mywiki.wooledge.org/BashFAQ/050 DMENU() { dmenu -i -p 'Kill'; } #looks better on xft powered dmenu: #https://bugs.launchpad.net/ubuntu/+source/suckless-tools/+bug/1093745 _usage() { printf "%s\\n" "Usage: ${progname} [PATTERN]" printf "%s\\n" "Dmenu window selector for i3-wm." printf "%s\\n" printf "%s\\n" " -h, --help show this message and exit" } _die() { [ -n "${1}" ] && _die_msg="${1}" || exit 1 printf "%b%b\\n" "${_die_msg}" ", press to exit" | DMENU exit 1 } _notify() { [ -z "${1}" ] && return 1 kill -9 $(pgrep notify-osd) >/dev/null 2>&1 if ! DISPLAY=${DISPLAY:-:0} notify-send -t 1000 "${1}" "${2}"; then if command -v "gxmessage" 2>/dev/null; then font="Monaco 9" DISPLAY=${DISPLAY:-:0} gxmessage "${font:+-fn "$font"}" "${1}" "ok" elif command -v "xmessage" 2>/dev/null; then font="fixed" DISPLAY=${DISPLAY:-:0} xmessage "${font:+-fn "$font"}" "${1}" "ok" fi fi } _get_process_names() { printf "%s\\n" "$(command ps xo command= | sed \ -e "s: .*::; s:.*/::; s/:$//;" \ -e "s:^\[.*\]$::" -e "/^$/d" \ -e "s:^$::")" | sort | uniq } if [ ! -t 0 ]; then #add input comming from pipe or file to $@ set -- "${@}" $(cat) fi for arg in "${@}"; do #parse options case "${arg}" in -h|--help) _usage && exit ;; esac done if [ -z "${1}" ]; then if ! command -v "dmenu" >/dev/null 2>&1; then printf "%s\\n" "${progname}: install 'dmenu' to run this program" >&2 exit 1 fi process_name="$(_get_process_names | DMENU)" else process_name="$(_get_process_names | grep -i "${@}" 2>/dev/null | head -1 )" fi if [ -z "${process_name}" ]; then _die else error_msg="$(kill -9 $(pgrep -x "${process_name}") 2>&1 1>/dev/null)" if [ X"${?}" != X"0" ]; then _notify "Error" "${error_msg}" exit 1 fi fi #vim:ft=sh