You are not logged in.

#1 2009-08-13 17:48:06

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

[SOLVED]new title: convert relative to absolute paths in bash

So the issue was not MPD, i hadn't noticed my script was creating a bad symlink when i passed it a relative path.  new problem, the simplest way to accept any relative path as argument and return an absolute path for use throughout the script.  i'm off to google...

my current version of the solution as a bashrc function:

rel2abs() {
  local file="$(basename "$1")"
  local dir="$(dirname "$1")"
  pushd "${dir:-./}" &>/dev/null && local dir="$PWD"
  echo "$dir/$file"
  popd &>/dev/null
}

:: OP ::

so i have this little script that is supposed to allow me to one-time-play an audio file sitting outside my mpd directory by creating a symlink to the file, updating the db, then playing the symlink.  everything's great accept mpd won't follow the symlink when creating/updating the db.

i've restarted mpd and re-create[d]-db both as myself (mpd runs as me) and as root many, many times.  it never changes.  the symlink file is never added to my database... is the manpage lying?  do i file a bug?  can anyone else reproduce?

i don't think it's a perm issue, mpd runs as me and the symlink's target and destination are both under ~/

┌─[ 13:30 ][ blue:~ ]
└─> pacman -Q mpd
mpd 0.15.1-1
man mpd.conf wrote:

follow_outside_symlinks <yes or no>
       Control if MPD will follow symbolic links pointing  outside  the  music  dir.   You  must
       recreate the database after changing this option.  The default is "yes".

follow_inside_symlinks <yes or no>
       Control  if  MPD  will  follow  symbolic links pointing inside the music dir, potentially
       adding duplicates to the database.  You must recreate the database  after  changing  this
       option.  The default is "yes".

/etc/mpd.conf wrote:

######################### OTHER OPTIONS ########################
gapless_mp3_playback                    "yes"
#save_absolute_paths_in_playlists       "no"
#metadata_to_use        "artist,album,title,track,name,genre,date,composer,performer,disc"
follow_outside_symlinks                 "yes"
follow_inside_symlinks                  "yes"

┌─[ 13:33 ][ blue:~ ]
└─> ll Music/temp/
total 0
lrwxrwxrwx 1 patrick patrick 36 2009-08-13 13:30 apocalyptica_beyond_time.mp3 -> Dropbox/apocalyptica_beyond_time.mp3
┌─[ 13:37 ][ blue:~ ]
└─> mpc ls temp
┌─[ 13:37 ][ blue:~ ]
└─>

i guess i can resort to simply copying the file into the temp directory rather than symlinking... but you archers know how it is, it just bothers you when something should work and it doesn't...

comments and pointers always appreciated.

Last edited by brisbin33 (2009-08-17 20:35:21)

Offline

#2 2009-08-13 18:11:07

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: [SOLVED]new title: convert relative to absolute paths in bash

It's a dead symlink: take a look at the part after -> again while inside Music/Temp

Offline

#3 2009-08-13 18:40:55

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: [SOLVED]new title: convert relative to absolute paths in bash

Procyon wrote:

It's a dead symlink: take a look at the part after -> again while inside Music/Temp

┌─[ 14:26 ][ blue:~ ]
└─> file Music/temp/apocalyptica_beyond_time.mp3
Music/temp/apocalyptica_beyond_time.mp3: broken symbolic link to `Dropbox/apocalyptica_beyond_time.mp3'

well, i'll be... so the issue is...

if i pass $1 to my script as directory/file.mp3 (which is fine relative to ~/, where i am in the filesystem), then ln doesn't know the difference so it symlinks to directory/file.mp3 which is ofcourse a stupid thing to do inside ~/Music/temp/.

let me think about a way to 'cleanse' $1 before symlinking...

i'll test and report back what i come up with (and also mark [SOLVED]).  thanks for the fresh set of eyes Procyon big_smile


EDIT: this is proving more difficult than i thought, anyone know the KISSest way to take a relative path and return an absolute path inside a bash script?

i can take care of ./* ~/* /* with a small case statement, but if possible, i'd like to account for all possibilities.

Last edited by brisbin33 (2009-08-13 18:55:02)

Offline

#4 2009-08-13 19:04:05

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: [SOLVED]new title: convert relative to absolute paths in bash

OK SOLVED

rel2abs() {
  cd "$(dirname $1)" && dir="$PWD"
  file="$(basename $1)"

  echo $dir/$file
}

Offline

#5 2009-08-13 19:51:30

firecat53
Member
From: Lake Stevens, WA, USA
Registered: 2007-05-14
Posts: 1,542
Website

Re: [SOLVED]new title: convert relative to absolute paths in bash

Mind posting your script? I've been using the following perl script to play a file outside of the music directory using mpd (found through the mpd wiki, I think). I'm up for a simpler solution if you found one!

#!/usr/bin/perl

# mpc-play
# version 0.2
# by Ilya "Voyager" Schurov (http://comm.noo.ru/iv-en/)

$MUSIC_PREFIX="/home/[username]/music";
$TEMP_DIR="tmp";
$SCRIPT_NAME="mpc-play";
# warning! all symlinks in $MUSIC_PREFIX/$TEMP_DIR will be lost on start!

$DEBUG=0;


$PWD=`pwd`;
chomp $PWD;

if(!@ARGV)
{
    print "Usage:\n$SCRIPT_NAME <files-to-play>\n";
}

say_and_do("mpc --no-status stop",$DEBUG);
say_and_do("mpc --no-status clear",$DEBUG);

# removing symlinks from $TEMP_DIR

while(<$MUSIC_PREFIX/$TEMP_DIR/*>)
{
        unlink if(-l);
}


foreach $file (@ARGV)
{
    $link=$file;
        
    # stripping slashes from arguments
    $link=~s/\//_/g;
    if($file!~/^\//)
    {
        $file="$PWD/$file";
    }
        
    symlink("$file","$MUSIC_PREFIX/$TEMP_DIR/$link") 
               || die("Can't create symlink from $file to $MUSIC_PREFIX/$TEMP_DIR/$link: $!");
    push @links, $link;
}
say_and_do("mpc update $TEMP_DIR",$DEBUG);

# now we need to wait while mpd updating DB
do
{
    $stat=`mpc`;
    sleep(0.1);
}while($stat=~/^Updating DB/m);

# generating playlist
foreach $link(@links)
{
    $link=~s/\`/\\\`/g;
    say_and_do("mpc --no-status add \"$TEMP_DIR/$link\"",$DEBUG);
}

#let's the music begins! :)
say_and_do("mpc play",$DEBUG);

sub say_and_do
{
    my $str=shift;
    my $debug=shift;
    print "$str\n" if($debug);
    system($str);
}

Thanks!
Scott

Offline

#6 2009-08-13 20:21:30

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: [SOLVED]new title: convert relative to absolute paths in bash

yeah, mines a bit shorter; and it's working really well so far:

#!/bin/bash
#
# creates a temp symlink to a file outside mpd DB
# adds it to the playlist and plays it
#
###

# usage: playnow [file]
[ $# -ne 1 ] && exit 1

# find our music directory
mdir="$(awk -F '"' '/^music_directory/ {print $2}' /etc/mpd.conf)"

# no matter what we pass, or where we are, we get
# an absolute path to the file we want. nifty.
file="$(basename $1)"
dir="$(dirname $1)"
cd ${dir:-./} && dir="$PWD" || exit 1

# clean the temp dir and make the new symlink
rm -rf "$mdir/temp"; mkdir "$mdir/temp"
ln -s "$dir/$file" "$mdir/temp/$file"

# update the db, add the new file, and play it
mpc --no-status update "temp/$file"
mpc --no-status add "temp/$file" &>/dev/null || exit 1
mpc play $(mpc playlist | wc -l)

exit $?

usage is simply `playnow some_file.mp3`.  i keep my system completely clean of spaces in filenames so if you have those you'll want to tweak some parts...

/edit: a slight simplification.

Last edited by brisbin33 (2009-08-13 20:36:59)

Offline

#7 2009-08-14 20:49:12

firecat53
Member
From: Lake Stevens, WA, USA
Registered: 2007-05-14
Posts: 1,542
Website

Re: [SOLVED]new title: convert relative to absolute paths in bash

I have spaces -- lots of spaces -- so I had to change \

file="$(basename $1)"
dir="$(dirname $1)"

to

file="$(basename "$1")"
dir="$(dirname "$1")"

and the ~/music wasn't being evaluated as an actual path (error: 'cannot create ~/music/temp'), so I came up with

mdir="$(awk -F '"' '/^music_directory/ {print $2}' /etc/mpd.conf)"
mdir=`eval echo "$mdir"`

To get mdir as an actual path. I'm sure there's a MUCH better way to do that, but I just keep trying things until they work smile

Works great now with spaces and ~ ! Think I'll switch smile You should get that added to the list of MPD hacks on their wiki.

Thanks!
Scott

Offline

#8 2009-08-17 20:18:13

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: [SOLVED]new title: convert relative to absolute paths in bash

thanks firecat, i've adopted your "$1" changes just because it makes the script more portable.

i'd also recommend this for the ~ issue: (i keep absolute paths in /etc/mpd.conf so i never got bit by that)

# find our music directory
mdir="$(awk -F '"' '/^music_directory/ {print $2}' /etc/mpd.conf)"
mdir="${mdir/\~/$HOME}"

odd, neither sed nor tr wanted to switch out ~ for $HOME easily, but the bashism works quite nicely.  One could probably put the switch right in the awk statement, but that's beyond me.

Offline

#9 2009-08-17 21:35:39

Gen2ly
Member
From: Sevierville, TN
Registered: 2009-03-06
Posts: 1,529
Website

Re: [SOLVED]new title: convert relative to absolute paths in bash

I'm a little tired so maybe I didn't understand the question, but to get a full un-qualified path you could use:

realpath -s /dir
realpath /dir

The former will follow a link to it's source.

Edit: bah, just re-read, I probably need to get some sleep.

Last edited by Gen2ly (2009-08-17 21:36:20)


Setting Up a Scripting Environment | Proud donor to wikipedia - link

Offline

#10 2009-08-18 06:35:48

firecat53
Member
From: Lake Stevens, WA, USA
Registered: 2007-05-14
Posts: 1,542
Website

Re: [SOLVED]new title: convert relative to absolute paths in bash

mdir="${mdir/\~/$HOME}"

What is that doing, exactly? I haven't seen that 'bashism' before?

Scott

Offline

#11 2009-08-18 13:34:53

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: [SOLVED]new title: convert relative to absolute paths in bash

"${mdir/\~/$HOME}" simply means "evaluate $mdir but switch any occurance of ~ with $HOME" so:

if $mdir="~/Music", then ${mdir/\~/$HOME/}="$HOME/Music"="/home/user/Music" which i believe solves our issue with mkdir.

Offline

#12 2009-08-18 15:56:20

firecat53
Member
From: Lake Stevens, WA, USA
Registered: 2007-05-14
Posts: 1,542
Website

Re: [SOLVED]new title: convert relative to absolute paths in bash

Ah, neat -- sort of like a shorthand sed search and replace I guess. Works great!

Thanks, Scott

P.S. thanks also for your dmenu cache script and light/dark grey colorscheme. I stole both of those for my dwm configs smile

Offline

Board footer

Powered by FluxBB