Get filename only (not absolute path) as $1 in shell script.

Get help. Get answers. Let others lend you a hand.

Moderator: Mr_Noodle

Is it possible to reference a relative filename only, relative to the directory where rules are being applied, instead of an absolute path and filename?

The reason is that I am matching rules on a folder that is stored on a NAS, and then I am sending a command to the NAS to be executed remotely over SSH, and the absolute path and filename from the machine where Hazel is running is not the same as the absolute path and filename on the NAS.

The rule is executing `cp -Rl $1 path/to/other/dir`. It's recursively hard linking downloaded files (torrents) to a watched dir on the NAS (to be processed) without removing the original files (so they can keep seeding). If $1 was the filename (relative to the dir my rules are applied to) I could just hard code the NAS part of the filename, e.g. `ssh me@nas cp -Rl "/mnt/pool/dataset/Torrents/$s" /mnt/pool/dataset/watchdir

I need to send the command through SSH to execute remotely because OS X doesn't support `cp -Rl`, and also doesn't seem to support hard linking files at all on the non-local volume being shared from my NAS.
mrmachine
 
Posts: 14
Joined: Thu Sep 05, 2013 10:52 am

use a variable and basename.
Code: Select all
NAME=$(basename "$1")
ssh "your command with $NAME instead of $1"
Skeo
 
Posts: 31
Joined: Mon Jan 02, 2012 7:53 pm

That would give me the filename, but none of the path (relative to the directory that Hazel is watching), right?
mrmachine
 
Posts: 14
Joined: Thu Sep 05, 2013 10:52 am

Thats right. Is that not what you want?
Skeo
 
Posts: 31
Joined: Mon Jan 02, 2012 7:53 pm

Ideally it would include the path relative to the Hazel directory being monitored, in the case that rules recurse into folders. I can do it with `${1#/path/to/hazel/directory/being/monitored/}`, but I have another problem when $1 expands to a name that includes a space. My rule is this:

ssh me@nas4free cp -lR "${1#/Volumes/dataset/}" "Downloads/complete"

But the double quotes are not passed through SSH when the command is executed remotely. I get errors about files not being found, because of the spaces. If I wrap the command in single quotes, then the $1 variable does not get expanded.

ssh me@nas4free 'cp -lR "${1#/Volumes/dataset/}" "Downloads/complete"'
mrmachine
 
Posts: 14
Joined: Thu Sep 05, 2013 10:52 am

ok, so.
I think I got what you want by using sed to sub the working directory with nothing in the filename.

Code: Select all
NAME=$(echo "$1" | sed "s:$PWD::")

so if $1 is /pathto/watchfolder/extrapath/to/file
then NAME would become /extrapath/to/file

I've not seen that # syntax before, but google just taught me all about substring removal. yay google.
I found that this also works and doesn't require hard coding the watch folder.

Code: Select all
${1#$PWD}

As far as your ssh problem and files with spaces, that can pretty easily be solved by using backslash quotes on your soft quotes inside your ssh command. Or you could use hard quotes around your file address, inside your soft quotes on your ssh command.
Pretty sure either of these could be your solution.

Code: Select all
ssh me@nas4free cp -lR "\"${1#$PWD}\"" "Downloads/complete"
ssh me@nas4free cp -lR "'${1#$PWD}'" "Downloads/complete"
Skeo
 
Posts: 31
Joined: Mon Jan 02, 2012 7:53 pm

I figured out the hard quotes inside soft quotes. Nice find with ${1#$PWD}, though! But I think I would need ${1#$PWD/} to also trim the trailing slash from the hazel rule folder (and avoid sending an absolute URL through SSH in the remote command)?

Thanks!
mrmachine
 
Posts: 14
Joined: Thu Sep 05, 2013 10:52 am

Yes you're right. I missed that.
Glad you got it working.
Skeo
 
Posts: 31
Joined: Mon Jan 02, 2012 7:53 pm


Return to Support