#!/bin/sh default_sink_name() { pactl stat | sed -ne 's/^Default Sink: //p' } die() { printf 'Error: %s\n' "$1" >&2 exit 1 } sink=$(default_sink_name) || die "could not determine default sink" set_volume() # uses $sink { pactl set-sink-volume "$sink" "$1"% } show_volume_line() # uses $sink { local want_next= pactl list sinks | while read line; do case "$line" in "Name: $sink") want_next=1 ;; 'Name: '*) want_next= ;; 'Volume: '*) [ "$want_next" ] || continue echo "$line" break ;; esac done } show_volume_number() # uses $sink { set -- $(show_volume_line) local total=0 num=0 p for p; do case "$p" in *%) total=$((total + ${p%%%})) num=$((num + 1)) ;; esac done if [ "$num" -gt 0 ]; then echo $(( total / num )) fi } case "$1" in [0-9]*) set_volume "$1" ;; [-+*/][0-9]*) set_volume $(( $(show_volume_number) $1 )) ;; '') show_volume_number ;; *) die 'usage' ;; esac