I am on UBuntu 16.04. I have asked a question here regarding headphones plug unplug event. What I tried didn't work. I want to use acpi_listen command to listen to headphones connected event and display a message using notify-send. How to use acpi_listen in a shell script?
2 Answers
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.

- 105,154
- 20
- 279
- 497
-
Simply elegant! Thanks a lot Serg. You have been helping me since I have migrated to Ubuntu. Thanks a lot! – thewebjackal Feb 03 '17 at 12:39
-
1+1. I read your edit comments on POSIX. So I have to change all my
==
to=
now? – WinEunuuchs2Unix Apr 19 '18 at 00:08 -
1@WinEunuuchs2Unix If you're working only with
bash
and Ubuntu, then it's OK, no need to change anything. When you work with multiple OS and rely on POSIX/bin/sh
then it'd better be POSIX compliant. Choice here is also because of[
. When you use[[
and==
, the stuff on the right is treated as regex pattern. You kinda have to be aware of that of there's special characters you're trying to match, like*
and^
. Pattern vs literal string, in other words – Sergiy Kolodyazhnyy Apr 19 '18 at 00:54 -
Serge, it's kind of over my head but I only use
#!/bin/bash
and read single[
invokestest
external command so I've been converting stuff to[[
built-in. As far as regex goes, Muru would be the first to tell you it gives me a headache :) – WinEunuuchs2Unix Apr 19 '18 at 01:26 -
@WinEunuuchs2Unix The
[
and[[
are tools, and you need right tool for the right job. If you are dealing with simple string comparison,[
is enough. But[[
is more powerful, and when you need that extra pattern matching power in shell scripts,[[
will be your friend. Compare[ "mystring" == *str* ]
and[[ "mystring" == *str* ]]
. When you havebash
, this is your pattern matching friend. Otherwise, if you only have/bin/sh
you may need complexcase
statement. – Sergiy Kolodyazhnyy Apr 19 '18 at 02:08 -
Compare also
( set -x ;[ *.txt == *txt ] && echo "Yes" )
vs( set -x ;[[ *.txt == *txt ]] && echo "Yes" )
The[[
won't perform filename globbing where you don't want it, i.e. when you are doing pattern and string comparison matching on variable, you don't want*
behave as file glob. There are better utilities for that already anyway, likefind
. – Sergiy Kolodyazhnyy Apr 19 '18 at 02:10
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

- 153
-
1So this works for
audacious
, but not for VLC? Is that what you're saying? nb. Once you've got > 200 reputation in one site, you will automatically get 100 reputation on any new SE site you join as a "trusted" user. Ref: https://meta.stackexchange.com/a/79783 – Benjamin R Jan 20 '19 at 16:19 -
@BenjaminR, I would work with
vlc
ifvlc
would have a command-line option to toggle play/pause (e.g.vlc --pause
). However, I could not find one invlc --help
. Or you know a way around it? I’m interested. :)And thank you for info about the reputation. I am just a occasional user of these sites—I search more than I ask (as I believe that ‘everything’ is on the Web).
– tukusejssirs Jan 20 '19 at 16:54 -
Check this answer out: https://stackoverflow.com/questions/14256193/linux-control-a-running-vlc-process-through-command-line – Benjamin R Jan 21 '19 at 13:12
udev
makes more sense thanacpi_listen
but you may find this thread interesting with many different answers for headphone control: http://askubuntu.com/questions/769593/16-04-headphones-detected-but-not-switched-on-automatically-after-startup – WinEunuuchs2Unix Feb 03 '17 at 01:45