You are not logged in.
Pages: 1
Topic closed
So I'm trying to write a script to halt my computer after the currently playing song is finished, as it's something I've been doing manually a lot. Problem is, I can't get it to work. Here's what I have so far:
#!/bin/bash
TMP_FILE="$HOME/bin/tmp/.mpd_end.tmp"
CMD="echo This is where the computer would halt."
# if the command is interupted, make sure $TMP_FILE isn't left behind
trap "rm $TMP_FILE; exit" SIGHUP SIGINT SIGTERM
# mpc should output 3 lines if a song is playing, but only 1 if it isn't
mpc > $TMP_FILE
# check to see if a song is playing by examining the line count of $TMP_FILE
# if there is one playing, get rid of extraneous lines in $TMP_FILE, otherwise exit with an error
if [ `wc -l $TMP_FILE` = "3" ]; then
head -n 1 $TMP_FILE > $TMP_FILE
else
echo "Error: no song is currently playing."
rm $TMP_FILE
exit 1
fi
# check every 2 seconds to see if the song is over, then move on
# currently the script doesn't even make it this far
while [ `mpc | head -n 1` = `cat $TMP_FILE` ]; do
sleep 2
done
rm $TMP_FILE
exec $CMD
I have no idea what is wrong with the code, but the errors I get are because $TMP_FILE never actually gets written for some reason. Any help?
EDIT: Oh, and I apologize for the lack of comments. I'll add those in a little bit, but I don't think it's that hard to understand, as long as you know that mpc will output 3 lines if a song is playing and only 1 line if it isn't.
EDIT: Comments added.
Last edited by fflarex (2008-09-12 12:16:16)
Offline
Seems
wc -l <file>
doesn't only print the number of lines in the file, but the file's name as well:
quentin@q-eee> mpc > test
quentin@q-eee> wc -l test
3 test
in which case your if condition will never be true.
Last edited by Arkane (2008-09-10 19:47:08)
What does not kill you will hurt a lot.
Offline
You can't open a file for reading and writing in the same line.
head -n 1 $TMP_FILE > $TMPFILE # Don't do this
sed -i '1!d' $TMP_FILE # Do this instead
Better yet, use another method.
mpc | awk '$NR == 2 && /^[playing]/ { print "playing" } > $TMP_FILE
Last edited by Daenyth (2008-09-10 20:00:21)
[git] | [AURpkgs] | [arch-games]
Offline
You sure it really does? ~/bin/tmp makes for a real weird director layout...
Last edited by Arkane (2008-09-10 22:48:06)
What does not kill you will hurt a lot.
Offline
Try putting "set -x" at the top of the script, and "set +x" at the bottom, then run it again. It might help you figure it out.
[git] | [AURpkgs] | [arch-games]
Offline
The solution follows: Requirements: Perl and mpc
#!/usr/bin/perl
$action = shift;
$song = `mpc|head -n1`;
do {
sleep(2);
$newsong = `mpc|head -n1`;
} while($song eq $newsong);
print "Song changed!\n";
print "Taking action: '$action'\n\n";
exec($action);
Name it something appropriate (mine is ~/bin/mpd-on-change) and call it (like mpd-on-change "sudo halt").
Should be easy to modify for playing/stopped status as well. (EDIT: actually, it works if MPD stops, because the first line of mpc output is different.)
Good luck
Last edited by gnud (2008-09-11 21:45:54)
Offline
Just for anybody who searched for this problem and ended up here:
This is some updated code by fflarex, which he posted in another thread -- same idea as mine above, but in bash, and with additional features.
#!/bin/bash
#
# ~/bin/mpd-on-change - Waits for MPD's status to change (usually the end of a
# song), and optionally executes an action afterwards.
# Print a help message
function usage {
echo "
mpd-on-change - Waits for MPD's status to change (usually the end of a song),
and optionally executes an action afterwards.
Usage: mpd-on-change [[-i | --interval] seconds] [[-n | --songs] songs] \\
[[-a | --action] command.. ]
Options:
-a, --action Execute some action after song(s) finish. Anything after this
option is taken to be a command.
-i, --interval Set the time between checking the current song. May be in any
format supported by sleep. Default is 2.
-n, --songs Set the number of songs to wait for. Default is 1.
-h, --help Display this help message and exit.
Note that stopping a song, or starting one when MPD is stopped, will signal a
change as if the song had finished. This script requires that mpc be installed
and MPD be running.
"
}
# What to do in case of incorrect usage
function error_exit {
usage
exit 1
}
# Makes sure mpc is installed and mpd is running
if [ `mpc | wc -l` -eq 0 ]; then
error_exit
fi
# $number is the number of songs to complete before finishing up
# $interval is the length of time between checking the current song
# $action is what is executed after the songs play
number=1
interval=2
action=:
# Detect command line arguments
while [ "$1" != "" ]; do
case $1 in
-a | --action ) shift
action=$*
break
;;
-i | --interval ) shift
interval=$1
;;
-n | --songs ) shift
number=$1
;;
-h | --help ) usage
exit
;;
* ) error_exit
esac
shift
done
# Tests that $number is a non-negative integer
test $number -ge -1 2> /dev/null || error_exit
# Tests to see if $interval is valid input for sleep
# Note that this adds an extra sleep command, which usually won't matter
sleep $interval 2> /dev/null || error_exit
# $song keeps track of which song needs to finish
# $cur_song is the currently playing song
song=`mpc | head -n 1`
cur_song=$song
# $count keeps track of how many songs have finished playing
# This is the meat of the program, which periodically checks the current song
count=0
until [ $count -eq $number ]; do
while [ "$cur_song" = "$song" ]; do
sleep $interval
cur_song=`mpc | head -n 1`
done
count=$((count + 1))
song=`mpc | head -n 1`
done
# Action to be executed at the end, default does nothing
$action
Offline
Just for anybody who searched for this problem and ended up here:
This is some updated code by fflarex, which he posted in another thread -- same idea as mine above, but in bash, and with additional features.#!/bin/bash # # ~/bin/mpd-on-change - Waits for MPD's status to change (usually the end of a # song), and optionally executes an action afterwards. # Print a help message function usage { echo " mpd-on-change - Waits for MPD's status to change (usually the end of a song), and optionally executes an action afterwards. Usage: mpd-on-change [[-i | --interval] seconds] [[-n | --songs] songs] \\ [[-a | --action] command.. ] Options: -a, --action Execute some action after song(s) finish. Anything after this option is taken to be a command. -i, --interval Set the time between checking the current song. May be in any format supported by sleep. Default is 2. -n, --songs Set the number of songs to wait for. Default is 1. -h, --help Display this help message and exit. Note that stopping a song, or starting one when MPD is stopped, will signal a change as if the song had finished. This script requires that mpc be installed and MPD be running. " } # What to do in case of incorrect usage function error_exit { usage exit 1 } # Makes sure mpc is installed and mpd is running if [ `mpc | wc -l` -eq 0 ]; then error_exit fi # $number is the number of songs to complete before finishing up # $interval is the length of time between checking the current song # $action is what is executed after the songs play number=1 interval=2 action=: # Detect command line arguments while [ "$1" != "" ]; do case $1 in -a | --action ) shift action=$* break ;; -i | --interval ) shift interval=$1 ;; -n | --songs ) shift number=$1 ;; -h | --help ) usage exit ;; * ) error_exit esac shift done # Tests that $number is a non-negative integer test $number -ge -1 2> /dev/null || error_exit # Tests to see if $interval is valid input for sleep # Note that this adds an extra sleep command, which usually won't matter sleep $interval 2> /dev/null || error_exit # $song keeps track of which song needs to finish # $cur_song is the currently playing song song=`mpc | head -n 1` cur_song=$song # $count keeps track of how many songs have finished playing # This is the meat of the program, which periodically checks the current song count=0 until [ $count -eq $number ]; do while [ "$cur_song" = "$song" ]; do sleep $interval cur_song=`mpc | head -n 1` done count=$((count + 1)) song=`mpc | head -n 1` done # Action to be executed at the end, default does nothing $action
how can i have this so it runs contently, and runs teh command on each song change?
Desktop: E8400@4ghz - DFI Lanparty JR P45-T2RS - 4gb ddr2 800 - 30gb OCZ Vertex - Geforce 8800 GTS - 2*19" LCD
Server/Media Zotac GeForce 9300-ITX I-E - E5200 - 4gb Ram - 2* ecogreen F2 1.5tb - 1* wd green 500gb - PicoPSU 150xt - rtorrent - xbmc - ipazzport remote - 42" LCD
Offline
how can i have this so it runs contently, and runs teh command on each song change?
Here's an updated version of the script which can do this with the new -r switch. It also runs on all POSIX-compliant shells now, instead of just bash (so you can, for example, change the first line to '#!/bin/dash' if you want faster performance).
#!/bin/sh
#
# ~/bin/mpd-on-change - Waits for MPD's status to change (usually at the end of
# a song), and optionally executes an action afterwards.
# TODO:
# recognize song changes when the title and artist are identical
# maybe add some kind of timeout or something (for when $nsongs is larger than
# the number of remaining songs in the playlist, a song is paused for way too
# long, or similar situations)
# Print a help message
usage() {
echo "
mpd-on-change - Waits for MPD's status to change (usually the end of a song),
and optionally executes an action afterwards.
Usage: mpd-on-change [[-i | --interval] time] [[-n | --songs] songs] \
[-r | --respawn] [[-a | --action] command.. ]
Options:
-a, --action Execute some action after song(s) finish. Anything after this
option is taken to be a command.
-i, --interval Set the time between checking the current song. May be in any
format supported by sleep. Default is 2.
-n, --songs Set the number of songs to wait for. Default is 1.
-r, --respawn Respawn the script after exiting.
-h, --help Display this help message and exit.
Note that stopping a song, or starting one when MPD is stopped, will signal a
change as if the song had finished. It also does not register song changes if
the title and artist of the songs are identical. This script requires that mpc
be installed and MPD be running.
"
}
# What to do in case of incorrect usage
error_exit() {
usage
exit 1
}
# Makes sure mpc is installed and mpd is running
if [ `mpc | wc -l` -eq 0 ]; then
error_exit
fi
# $action is what is executed after the songs play
# $interval is the length of time between checking the current song
# $nsongs is the number of songs to complete before finishing up
# $respawn is whether or not to respawn after exiting
action=:
interval=2
nsongs=1
respawn=false
# Detect command line arguments
while [ "$1" != "" ]; do
case $1 in
-a | --action ) shift
action="$@"
break
;;
-i | --interval ) shift
interval=$1
;;
-n | --songs ) shift
nsongs=$1
;;
-r | --respawn ) respawn=true
;;
-h | --help ) usage
exit
;;
* ) error_exit
esac
shift
done
# Tests that $nsongs is a non-negative integer
test $nsongs -ge -1 2> /dev/null || error_exit
# Tests to see if $interval is valid input for sleep
# Note that this adds an extra sleep command, which usually won't matter
sleep $interval 2> /dev/null || error_exit
# $song keeps track of which song needs to finish
# $cur_song is the currently playing song
song=`mpc | head -n 1`
cur_song=$song
# $count keeps track of how many songs have finished playing
# This is the meat of the script, which periodically checks the current song
count=0
until [ $count -eq $nsongs ]; do
while [ "$cur_song" = "$song" ]; do
sleep $interval
cur_song=`mpc | head -n 1`
done
count=$(($count + 1))
song=`mpc | head -n 1`
done
# Action to be executed at the end, default does nothing
$action
# Respawn if the -r command line switch was used
if `$respawn`; then
exec mpd-on-change --interval $interval --songs $nsongs \
--respawn --action $action
fi
EDIT: Please see the new and improved mpd-wait, the direct successor to this script.
Last edited by fflarex (2009-08-23 01:43:30)
Offline
For anyone searching this, all of this can be done really easily without a script. See:
% mpc current --wait
This waits until the current song is finished (even if you have 'continue' on, which the above solutions will miss)
So you can do something like:
% mpc current --wait ; shutdown ....
Offline
Daveola: Welcome to the forums. Thanks for the suggestion, but pay attention to the dates on threads. This one has been quiet for 11 years.
Using this opportunity to close.
Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way
Offline
Pages: 1
Topic closed