statusdir=$XDG_RUNTIME_DIR/statusbar
mkdir -pm0700 "$statusdir"
inotifywait -rqme close_write --format %f "$statusdir" | while read -r file; do
if read -r -- "$file" < "$statusdir/$file"; then
# ...
fi
done
inotifywait
can watch a directory of files. When one of those files triggers
the close_write
event a new variable can be synthesised based on the file
name using read
. The new variable will contain the first line of data from
the file itself.
These new variables can be used with printf
to create a formatted string
designed for use in a typical statusbar.
If using bash it may also be possible to load the sleep
loadable so in the
rare case it is needed the cost of fork and exec can be eschewed.
enable -f "$(pkg-config --variable=loadablesdir bash)"/sleep sleep
Note
|
This event loop can be arbitrarily fast. Any pre-formatting should
be done before the values are written to files watched by
inotifywait so only a minimum amount of work is needed display them
inside the loop.
|
Some status updates which cannot be done using notification and have usually long intervals can be easily provided with per-user crond or systemd.timer services.
For example given a battery-status
script, we could run it every five
minutes using the following crontab:
*/5 * * * * battery-status > "$XDG_RUNTIME_DIR"/statusbar/battery
Although all these examples are simple sh
scripts it does not mean only
shell can be used. Any language capable of writing files (even to stdout)
is suitable for this.
#!/bin/sh --
statusdir=$XDG_RUNTIME_DIR/statusbar
mkdir -pm0700 "$statusdir"
fmt='[[%artist% - ]%title%]|[%file%]'
mpc current -f "$fmt" > "%statusdir"/mpd
mpc idleloop | while read -r event; do
case $event in
player) mpc current -f "$fmt" > "%statusdir"/mpd
esac
done
Use pactl subscribe
to provide real-time volume notification for default
sinks.
Note
|
One potential improvement would be to pair this with another
pacmd running as a "daemon" using exec_with_pipe
to accept commands over a control fifo thereby avoiding execution
of multiple pulseaudio clients.
|
#!/bin/sh --
statusdir=$XDG_RUNTIME_DIR/statusbar
datadir=$statusdir/data
mkdir -pm0700 -- "$statusdir" "$datadir"
if ! pulseaudio --check; then
printf 'statusbar: pulsemonitor: pulseaudio not running\n' >&2
exit 1
fi
pastat() {
pactl -f json list "$1" | jq -r '
.[] | select(.state == "RUNNING" and (.muted | not)).volume
| [keys_unsorted[] as $k | .[$k].value_percent[:-1] | tonumber]
| add / length'
}
# Initial values.
pastat sinks > "$datadir"/vol
pastat sources > "$datadir"/mic
mkfifo -- "$statusdir"/pulsemonitor.pipe
pactl subscribe > "$statusdir"/pulsemonitor.pipe &
while read -r _ event _ type _; do
if [[ $event = \'change\' ]]; then
case $type in
sink) pastat sinks > "$datadir"/vol ;;
source) pastat sources > "$datadir"/mic
esac
fi
done < "$statusdir"/pulsemonitor.pipe