Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

boast

macrumors 65816
Nov 12, 2007
1,407
860
Phoenix, USA
I am trying to get this to work on Yosemite. I know my applescript is in the right place and is working correctly, and the command I put in the shell script works. The problem is in the shell script. I have put the echo commands in each case as directed to figure out which case it is choosing, but no debug file appears on the desktop, so I guess it is not choosing any of them? If I put an echo debug command before the case $SSID line then i get a file, normal with the same thing printed several times. Any ideas? Thanks in advance.

BTW, the only thing I need to do after editing my locationchanger script file is replace the current one in the /bin folder, then unload and load the plist in terminal correct? I am using a modified version of the original, not my own.


I think you might have to escape the ’ in your SSID name

'Alex\’sNetwork'
 

alexk403

macrumors member
Jul 24, 2012
59
1
Thanks for the reply, but it is still not working. I have posted my location changer as you can see, and the plist is the exact one maxl posted but I changed the watched file to the one another poster said you needed to change it to in order for it to work on Yosemite. I have tried it with the original as well and still doesn't work. Also, still can't get an echo debug file to be written in any of the cases, so I think it has something to do with the shell script. Thanks.
 

boast

macrumors 65816
Nov 12, 2007
1,407
860
Phoenix, USA
Thanks for the reply, but it is still not working. I have posted my location changer as you can see, and the plist is the exact one maxl posted but I changed the watched file to the one another poster said you needed to change it to in order for it to work on Yosemite. I have tried it with the original as well and still doesn't work. Also, still can't get an echo debug file to be written in any of the cases, so I think it has something to do with the shell script. Thanks.

Do an echo $SSID before the case statement and see what it says.
 

alexk403

macrumors member
Jul 24, 2012
59
1
Do an echo $SSID before the case statement and see what it says.

just echo $SSID or do I need to write it to a debug file like before?

----------

Alright now we are getting somewhere. I put in an echo SSID with the debug file, and then commented out the grabbing the SSID and instead just put SSID='test', so the debug file contained 'test'. Then I put back the regular SSID command and the debug file is blank. So it looks like that command is not storing the SSID into the variable. I am on Yosemite so maybe something has changed since then that that command no longer works? Thanks.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,706
8,346
A sea of green
Thanks for the reply, but it is still not working. I have posted my location changer as you can see, and the plist is the exact one maxl posted but I changed the watched file to the one another poster said you needed to change it to in order for it to work on Yosemite. I have tried it with the original as well and still doesn't work. Also, still can't get an echo debug file to be written in any of the cases, so I think it has something to do with the shell script. Thanks.

The problem in your script is here (in a large font, in red):
Code:
case $SSID in 
	
	# Home network SSID
	[SIZE="4"][COLOR="Red"]‘Alex’sNetwork’[/COLOR] )[/SIZE]
Those are curly quotes. The part in red needs to be changed to exactly this:
Code:
[SIZE="4"]"Alex'sNetwork"[/SIZE]
You should copy and paste that in, rather than typing it in.

I made it the same large font size as the one in red. You should be able to see slight differences in the quoting characters used. If not, zoom in with your browser.

There may be other problems. This is just the most obvious one, given what you've posted.


Exactly what editor are you using to edit this shell script?

If it's TextEdit, then you need to look in its Preferences window for "Smart Paste" and/or "Smart Quotes" and DISABLE those BEFORE pasting the above into the shell script.

After you save the file, close and reopen it. Then copy and paste the edited line into a reply here. If it still has curly quotes, we'll be able to see it.

When posting shell scripts, commands, and such, please use code tags.


I think you might have to escape the ’ in your SSID name

'Alex\’sNetwork'
Backslash escapes don't work within single quotes (see 'man bash'):
Enclosing characters in single quotes preserves the literal value of
each character within the quotes. A single quote may not occur between
single quotes, even when preceded by a backslash.


If the quotes were all straight single-quotes, it would have to be this:
Code:
'Alex'\''sNetwork'
That is, you have to close the initial single-quoted part, escape a single single-quote, then make a final single-quoted part.

Since the text is completely literal (nothing that gets expanded between double quotes), the simplest and clearest thing to do in this particular case is to enclose the apostrophe'd string in double quotes (as shown above). A completely generalized solution is more complex, and depends on the exact SSID of the network.

Shell quoting is more complicated than most people realize, even people familiar with shell quoting.
 

alexk403

macrumors member
Jul 24, 2012
59
1
Thanks a lot for your help. That is definitely what was hanging my up. My locationchanger script now works correctly when manually executed, but is not working when I change networks, so I guess there is something wrong with the plist? Here is my locationchanger script located at /bin/locationchanger and the current plist file at ~/Library/LaunchAgents/LocationChanger.plist . Note I have changed the watched file as another poster mentioned to get it working with Yosemite, but I have tried the original method as well. Thanks in advance.

Code:
#!/bin/bash

# automatically mount network volume when connected to home network

# redirect all IO to /dev/null
exec 1>/dev/null 2>/dev/null

# wait 2 seconds for connection to be established
sleep 2

# current SSID
SSID=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I\ | grep ' SSID:' | cut -d ':' -f 2 | tr -d ' '`

# home network SSID (no spaces)
homeNet=‘Alex\’sNetwork’

if [[ “$SSID” == “$homeNet” ]] ; then
	
	# run mountVolume AppleScript
	osascript ~/prog/AppleScript/mountVolume.scpt

	# display notification that volume was mounted
    osascript -e 'display notification "Your media can now be accessed." with title "Entertainment Drive Mounted"'

fi

exit 0

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>my.locationchanger</string>
	<key>ProgramArguments</key>
	<array>
		<string>/bin/locationchanger</string>
	</array>
	<key>WatchPaths</key>
	<array>
		<string>/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist</string>
	</array>
</dict>
</plist>
 

chown33

Moderator
Staff member
Aug 9, 2009
10,706
8,346
A sea of green
Thanks a lot for your help. That is definitely what was hanging my up. My locationchanger script now works correctly when manually executed, but is not working when I change networks, so I guess there is something wrong with the plist? Here is my locationchanger script located at /bin/locationchanger and the current plist file at ~/Library/LaunchAgents/LocationChanger.plist . Note I have changed the watched file as another poster mentioned to get it working with Yosemite, but I have tried the original method as well. Thanks in advance.
...
Your shell script has curly quotes again. Look here:
Code:
# home network SSID (no spaces)
homeNet=[COLOR="Red"][SIZE="4"]‘Alex\’sNetwork’[/SIZE][/COLOR]

if [[ [COLOR="Red"][SIZE="4"]“$SSID” == “$homeNet”[/SIZE][/COLOR] ]] ; then
These aren't doing what you seem to think they're doing.

Please identify your text editor. It's important or I wouldn't ask for it.

You need to change your text editor's preference so it doesn't enter curly quotes ("Smart Quotes") when you type or paste in straight quotes. This is important, too.

Accuracy is important in programming, and when an editor "smartens" quotes, it breaks commands and shell scripts.

The lines I picked out above should be changed to exactly this:
Code:
homeNet="Alex'sNetwork"

if [ "$SSID" == "$homeNet" ] ; then
Your text editor must be told to NOT smarten the quotes. You must do that BEFORE pasting or entering the corrected lines.


Or maybe you have Text Replacement enabled, and the curly quotes are coming when you paste into a post. In that case, either disable Smart Quotes in Sys Prefs > Language > Text > Smart Quotes, or upload the actual shell script as an attachment to your post.
 

alexk403

macrumors member
Jul 24, 2012
59
1
Well slap my ass and call me Sally, thank you so much. The reason I left it with the curly quotes was because the program was working as it should (when executed manually), but you are absolutely right it should still be done the correct way. And what do you know, once I changed it to how you told me it now correctly works with the plist. Thanks a lot. I am pretty new to this stuff but was able to get through it with your help.

Hmmm, any way to get the program to mount the drive at startup/login as well? I know you can add the drive as a login item but I only want it to try and mount it if it is connected to the right network. Thanks.
 
Last edited:

chown33

Moderator
Staff member
Aug 9, 2009
10,706
8,346
A sea of green
Well slap my ass and call me Sally, thank you so much. The reason I left it with the curly quotes was because the program was working as it should (when executed manually), but you are absolutely right it should still be done the correct way. And what do you know, once I changed it to how you told me it now correctly works with the plist. Thanks a lot. I am pretty new to this stuff but was able to get through it with your help.
I'm glad you got it working, Sally. ;)

Hmmm, any way to get the program to mount the drive at startup/login as well? I know you can add the drive as a login item but I only want it to try and mount it if it is connected to the right network. Thanks.
Set the locationchanger script as a login item. It already checks to see if the network is right. So if you run that script and the network isn't right, nothing happens.

Since it's often easier to set apps or documents as login items, you could make an Automator workflow (use the Application template) and give it a single Run Shell Script action. That action would be to run your shell script. That is, it should contain the single line:
Code:
/bin/locationchanger
Then be sure to save the workflow as an application, and add it to your login items.
 

alexk403

macrumors member
Jul 24, 2012
59
1
Excellent! Thanks a lot. Alright next question for optimization. (Sorry I am always thinking of how I can make it better.) As other people have mentioned in this post and I have experienced myself often times if I am waking the computer from sleep there will be like 10 notifications that my media is ready to be accessed. I am assuming this is because the watched file (wifi networks whatever) is changing during wake/sleep and whatnot.

I was thinking one possible solution would be for the called applescript to check if the volume is already mounted or not, and return some value back to the shell script indicating if the applescript mounted the drive or if it was already mounted (and i guess you could have a third option that it wasn't able to mount it). Then the shell script could use that value to either notify you the drive was mounted, say there was an error, or do nothing (if the drive was already mounted). Is something like this possible? Maybe not like this but if we could somehow make everything internal to the shell script so it wouldn't have to call an applescript. I.e. you would need to be able to mount network drives and check if network drives are mounted from within the shell script. Just something I was thinking. Thanks.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,706
8,346
A sea of green
Excellent! Thanks a lot. Alright next question for optimization. (Sorry I am always thinking of how I can make it better.) As other people have mentioned in this post and I have experienced myself often times if I am waking the computer from sleep there will be like 10 notifications that my media is ready to be accessed. I am assuming this is because the watched file (wifi networks whatever) is changing during wake/sleep and whatnot.

I was thinking one possible solution would be for the called applescript to check if the volume is already mounted or not, and return some value back to the shell script indicating if the applescript mounted the drive or if it was already mounted (and i guess you could have a third option that it wasn't able to mount it). Then the shell script could use that value to either notify you the drive was mounted, say there was an error, or do nothing (if the drive was already mounted). Is something like this possible? Maybe not like this but if we could somehow make everything internal to the shell script so it wouldn't have to call an applescript. I.e. you would need to be able to mount network drives and check if network drives are mounted from within the shell script. Just something I was thinking. Thanks.

Start by posting what's in your "~/prog/AppleScript/mountVolume.scpt". As before, please use CODE tags, and copy/paste the AppleScript text exactly.

It's possible to look for a mounted volume using shell commands, but we have to know what to look for. Currently, that's all done inside your "mountVolume.scpt", so we need to see what's inside.


If you know anything about AppleScript itself, you could move this line:
Code:
    osascript -e 'display notification "Your media can now be accessed." with title "Entertainment Drive Mounted"'
inside your "mountVolume.scpt". The 'osacript' command is how you run AppleScript from inside a shell script. So what that command is doing is basically the same as if this were the last line of "mountVolume.scpt":
Code:
display notification "Your media can now be accessed." with title "Entertainment Drive Mounted"
You could then put any AppleScript conditionals or checks or whatever before that line, and it would only send the notification if those conditionals, checks, whatever were true.

Personally, I think it's a little odd that it wasn't done that way in the first place. That is, put all the AppleScript stuff in one place: in an AppleScript. Put all the shell script stuff in one place: in a shell script. Mixing things just makes it harder to keep track of.

If you don't know anything about AppleScript, just post what's inside "mountVolume.scpt" right now and we'll take it from there.
 

alexk403

macrumors member
Jul 24, 2012
59
1
Hey thanks for responding. I have gotten quite far since my last post, and have actually solved most of what I was talking about, but seem to have one last issue. I am fairly familiar in AppleScript (I am currently writing an entire program in it) and the only thing I had in there was a try block mounting the volume you will see below. Here is my current locationchanger shell script.
Code:
#!/bin/bash

# automatically mount network volume when connected to home network

# redirect all IO to /dev/null
exec 1>/dev/null 2>/dev/null

# wait 2 seconds for connection to be established
sleep 2

# current SSID
SSID=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I\ | grep ' SSID:' | cut -d ':' -f 2 | tr -d ' '`

# home network SSID (no spaces)
homeNet="Alex'sNetwork"

# volume to be mounted
volume="Entertainment"

if [[ "$SSID" == "$homeNet" ]] ; then

	#check if volume is already mounted
	if mount|grep $volume; then
		exit 1
	else
		#create volume directory
		mkdir /Volumes/Entertainment

		#mount volume
		mount -t afp afp://DiskStation._afpovertcp._tcp.local/Entertainment /Volumes/Entertainment

		# display notification that volume was mounted
    	osascript -e 'display notification "Your media can now be accessed." with title "Entertainment Drive Mounted"'
	fi
fi

exit 0

As you can see, I was able to figure out how to check if the volume is already mounted, as well as mounting the volume using shell. BTW, if there is a way to make the nested if statement a NOT equal to, let me know because then I would be able to get rid of the else and just put the mounting in the if statement if you get what I mean. The current problem I have is that everything works, but it mounts the volume as a guest, when I would like it mount as my user. I don't really want to hardcode my password in the script though, so I was able to find a way to grab it from the keychain. The problem is it is still not working. I believe it is because my password is a long string of random letters, numbers, and special characters, which is throwing off the command. Is there anyway around this, or do I just have to change my password to only letters and numbers? Thanks in advance, and below is the get password thing I was talking about.

Code:
get_pw () {
  security 2>&1 >/dev/null find-generic-password -ga $USER \
  |ruby -e 'print $1 if STDIN.gets =~ /^password: "(.*)"$/'
 }

mkdir /Volumes/Entertainment

mount -t afp afp://$USER:$(get_pw)@DiskStation._afpovertcp._tcp.local/Entertainment /Volumes/Entertainment
 
  • Like
Reactions: liquefry

alexk403

macrumors member
Jul 24, 2012
59
1
Haven't been able to get this to work since El Capitan. Looks like the install deleted my locationchanger from /bin and I no longer have write privileges to the /bin folder.
 

alexk403

macrumors member
Jul 24, 2012
59
1
alright boys, loaded up 10.12 sierra and looks like this script doesn't work anymore (at least for me). Specifically, you now need sudo privileges to write the /Volumes, so when the bash script runs
Code:
mkdir /Volumes/VOLUME_NAME
it stops there. Not sure if anyone else if running into this. Any ideas?
 

onyxgaze

macrumors newbie
Aug 17, 2009
4
0
Hi,

I am using Mojave Ver. 10.14.1 on a MB Pro.

Is there a feature in this OS version to automatically mount network share after connecting to a specific Wireless Network?

Or, would I need to write an Apple Script/ Shell script as in the discussion above?

That said, if a script is required, how do I go about doing this. I am new to scripting.

Thanks in advance.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.