Using acpi_listen command in a shell script

Writing script like that is fairly simple - you need to pipe acpi_listen to while IFS= read -r line ; do ... done structure, and take care of handling the events within that structure. The read shell builtin command will wait for a line of text from acpi_listen and processing will occur when the if statement sees that the line contains appropriate text. Alternatively, one could use case statement for better portability of the script.

Here's the simple script I personally would use. Tested on Ubuntu 16.04 LTS

#!/bin/bash
acpi_listen | while IFS= read -r line;
do
    if [ "$line" = "jack/headphone HEADPHONE plug" ]
    then
       notify-send "headphones connected"
       sleep 1.5 && killall notify-osd
    elif [ "$line" = "jack/headphone HEADPHONE unplug" ]
    then
       notify-send "headphones disconnected"
       sleep 1.5 && killall notify-osd
    fi
done

Note that if you plan to run this from cron job or via /etc/rc.local, you would need to export your DBUS_SESSION_BUS_ADDRESS for notify-send to work.


I was looking for something similar, but instead of a notification, I wanted to pause when unplugged (and the music was playing) and play when plugged in (and the music was paused).

I know, this is not exactly what the OP asked for, but I can’t comment here (what a pity that Stack Exchange sites don’t accumulate reputation score each other).

Anyway, here’s modified script of the @Sergiy’s one. I don’t say it is optimised or whatever, but it is working. I would be glad if someone (a Basher Pro? ;p) would improve it. :)

Btw, I tried using it with vlc (or cvlc, nvlc), but I couldn’t find a way to toggle play/pause from terminal when vlc was running in background (what I do all the time).

And note that I use audacious player—if you use whatever else, you need to change $state variable and playing/pausing commands.

UPDATE Added control for vlc (based upon this answer, as @BenjaminR has pointed out).

# Play/pause music like in smartphones

# Play when the headphone was plugged in,
# pause when the headphone was unplugged

# As there is no separate option in Audacious
# for playing even if it is already playing
# (or for pausing even if it is already paused),
# only toggles (e.g. play when paused, otherwise pause),
# I was forced to check the state of playback
# from PulseAudio (using `pacmd`).

# Added control for vlc (src: https://stackoverflow.com/a/43156436/3408342)

#!/bin/bash
acpi_listen | while IFS= read -r line; do
    test=$(pacmd list-sink-inputs | grep "application.process.binary\|state" | \sed 's/[="]//g' - | awk '{print $2}')
    if [[ $test ]]; then
        stateAud=$(echo "$test" | grep audacious -B1 | head -1)
        stateVlc=$(echo "$test" | grep vlc -B1 | head -1)

        # Play music when headphone jack has been plugged in AND the stateAud is corked/paused
        if [[ "$line" = "jack/headphone HEADPHONE plug" && $stateAud = "CORKED" ]]; then
            audacious -t
        fi
        if [[ "$line" = "jack/headphone HEADPHONE plug" && $stateVlc = "CORKED" ]]; then
            dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Play
        fi
        if [[ "$line" = "jack/headphone HEADPHONE unplug" && $stateAud = "RUNNING" ]]; then
            audacious -t
        fi
        if [[ "$line" = "jack/headphone HEADPHONE unplug" && $stateVlc = "RUNNING" ]]; then
            dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause
        fi
        echo
    fi
done