Jump to content
Subject22

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?

Share this post


Link to post

is there any reason you couldn't just use:

osascript -e 'tell application "iTunes" to pause'

as your command?

This will run/work regardless of whether or not iTunes is running to simply pause.

Share this post


Link to post

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 :)

Share this post


Link to post

I have to admit I am perplexed as to why it doesn't work, except in the applescript editor ... that's the only reason I suggested a more direct approach to tell iTunes to pause. 

Share this post


Link to post

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.

Share this post


Link to post

[Crazy magic]

Yeah, that's bizarre, and awesome. I'm quite happy with that workaround, thanks! I wonder if there's a way to view the output from the Applescript compiler. There could conceivably be some informative message in there.

Share this post


Link to post

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:

#!/usr/bin/osascript
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
		pause
	else
		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).

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...