Jump to content

Applescript doesn't function properly when called from Bash

Recommended Posts

This isn't directly related to Alfred, but I need to call an Applescript in one of my workflows (I can't run it directly from the workflow because reasons) and for some reason it's not working. Here's the relevant snippet.

if application "iTunes" is running then
	tell application "iTunes"
		set state to (get player state as string)
		if state is "playing" then pause
	end tell
end if

When I run that from Script Editor everything works just fine (iTunes pauses if it was playing, if it was running). But if I save that as a script and run it from Bash with osascript my_script.scpt nothing happens. No error message, nothing. iTunes keeps on playing.


Anyone have any wisdom they can impart?

Link to comment

Yes, there is. There's some additional logic in the script I took that snippet from. I pause iTunes, play a sound file, and then resume iTunes, but only if it was playing to start with. That's why I need to control playback within the script (I need to know if iTunes was playing to start with before I tell it to start playing again).

There are some fairly nasty workarounds that I can think of, but what I really want to know is why the script can't control iTunes when called from the shell. It's very irritating!

Cheers for the reply :)

Link to comment

It works just fine for me from bash.


All I did was copy/paste the snippet in the OP into a file called test.scpt. I opened iTunes, pressed play on the first track (which, apparently is a Ke$ha track... don't ask). Then, in iTerm I entered the command `osacript test.scpt`, and iTunes paused just fine.


But, let's get a bit more specific. To create the script, I did `nano test.scpt` from in iTerm and copy/pasted there.


As a curiosity, I tried it again by saving it through Script Editor as `test2.scpt`. The script would work correctly when run from Script Editor, but it wouldn't work via the Bash command. So I can reproduce your problem that way.


So there has to be a problem with the way that Script Editor is saving that particular script. When I `cat test.scpt`, then I see the script. When I `cat test2.scpt`, then I get the binary version of the script (garbled text). The size difference is 

staff      1952 Mar  4 11:45 test2.scpt
staff       163 Mar  4 11:35 test.scpt

So, 163 bytes vs 2kb. Weird, right?


So, I propose a work around: save the script as plain text rather than as a compiled binary script file. While the latter should work, something is making it not work.

Link to comment

Well, `osadecompile` doesn't help because it gives you the exact text that you typed in (I was curious if it would). What's hilarious is that this code works:

osascript -e "$(osadecompile test2.scpt)"

But, of course, that's just dumb.


But, the source of the problem is that, when compiled, "state" is not returned as a string (even though you request it as one).


When I try this code:

tell application "iTunes"
	set state to (get player state as string) as string
	if state is "playing" then
		do shell script "echo is playing: " & state
		do shell script "echo not playing: " & state
	end if
end tell

Then, when playing, I get "not playing: «constant ****kPSP»", and when it is not playing, I get "not playing: «constant ****kPSp»". So, the difference is the big v little p at the end of the constant, but the problem is that it is a constant and not a string.


The actual fix is the following:

if application "iTunes" is running then
	tell application "iTunes"
		if player state is playing then pause
	end tell
end if

In other words, if you don't try to make it into a string, then it just works. (Both from the command line and from the script editor).

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...