'say' command and 'without waiting until completion'


When I run the following script with or without the ‘waiting until completion’, both versions sounds the same to me. I thought without waiting would make the sounds overlap. What is happening?

Edited: oops, forgot the script:

set theDigits to "0123456789"
repeat 10 times
	set n to (some character of theDigits) as integer
	say n --without waiting until completion
end repeat

Edited: and btw, I think I’ve heard them overlap before.


That’s ok. Think I’ve figured it out. ‘say’ uses carbon. I was thinking about threads but can’t figure out that part.

Thanks anyway,

Just because the script doesn’t wait for completion doesn’t mean multiple instances of the speech synthesiser can run at once. Presumably the requests get queued. It’s nothing to do with Carbon.

I’ve heard them talk together. It’s good to have the tools now!


Hello kel.

Using the commandline say command can make the speach clutter if that is what you want.

Hi Shane and Mcusr,

Long time no see. :slight_smile: It works in parallel in unix! I guess just AppleScript needs to wait for use. Now I’m wondering if when run from AppleScript with osascript if it will work.

Just need to add some slight delays.

Thanks a lot,

Yes, it doesn’t work with osascript:

do shell script "osascript -e 'say \"hello\" without waiting until completion'"

The “&” is necessary.

Thanks a lot,

AppleScript, more precisely do shell script command, waits for bash to be complete based on stdout and stderr of the shell it opens. To run an command in the background you need to redirect both file descriptors. Like in my tutorial about running AppleScript in the background I prefer to redirect to /dev/null if you don’t need to command’s result.

Here is an example commandline kel.

do shell script "say 'Hi ' & say 'Hello ' & say 'hey there ' 2>&1 >/dev/null &"

As you can see, I redirect stderr, to stdout, and then I redirect stdout to /dev/null before I send the last process to the background, this works as DJ described. The do shell script command doesn’t hang around waiting, since there will be no output from its arguments.

Think I remember that, but can’t find the scripts. I know it was something like this:

-- command > /dev/null 2>&1
do shell script "2>&1 osascript -e 'say \"hello\" without waiting until completion' >/dev/null"

I’ll search MacScripter, but can’t remember what the main topic was.


Hi DJ,

Found it. I just needed to search for “/dev/null unix”. I’ll see if it works.

Thought I had it but it doesn’t work:

do shell script "osascript -e 'say \"hello\" without waiting until completion' 2>&1 >/dev/null; sleep 3"

I’m thinking that you need the parallel processes.

I meant this topic :slight_smile:

You also don’t need to redirect stderr to stdout because stderr remains attached to stdout and you need to redirect both. You can simply use &> which directs both stdout and stderr. At least what I mean was:

do shell script "say 'Hello World' &>/dev/null &"

Hello kel.

The say command is a stand alone commandline tool on Mavericks at least, it resides in /usr/bin, if it doesn’t work by the path directly from the do shell script. Therefore you don’t need osascript to run it, if you run Mavericks.

Hi Mcusr,

I know about the unix ‘say’ command and the Standard Additions ‘say’ command, but both of them don’t work without the “&” I think.

do shell script "osascript -e 'say \"hello\"' & say \"googoobaabaa\""

Interesting stuff. Ultimately, what I want to do is interrupt the last word from a speaker. Something like reality.

Have a good day,

I’m sorry to ask you this, but have you read my latest post above? It worked on my machine (Mavericks) as it does with all shell commands. Again, don’t use 2>&1 but use &> instead which is a shorthand for 1>… 2>….

I don’t really see the difference between 2>&1 and &> as long as the final redirection to a file appears as last argument.
My speech synthesizer crashed when I tried to use it with osascript command sent to background under Mavericks. I believe the osascript command has some own takes on ttys/ptys. Anyways . . it is easier to make the say command work as it should than having an applescript, execute the do shell script command, which in turn executes the osascript binary . . . :slight_smile:

Hi DJ and Mcusr,

What I was trying to do was to just get the AppleScript ‘say’ command’s ‘without waiting until completion’ parameter working. Without the ‘do shell script’ it doesn’t work with another ‘say’ command. In unix it doesn’t say anything with osascript:

do shell script "(osascript -e 'say \"hello world\" without waiting until completion' &>/dev/null &); say \"I'm done\""

It doesn’t say “hello world”. Mcusr’s unix say command works in parallel with the “&” as well as the Standard additions say command with the 'waiting until completion.

Now the trick will be in getting the last word. Doing some review with the embedded speech commands. Maybe there’s something there I can embed in the text, just before the last word.

Thanks a lot,

That is correct but maybe this quote from the bash manual makes it clears what I meant (NOTE: the order is important):

So what happens is that you redirect stderr to stdout and then redirect stdout to a file (which doesn’t redirect the file descriptor stderr). When you first redirect stdout to a file and then redirect stderr to stdout it will be redirected to the file as well. So if you still want to use 2>&1 you should redirect stdout before redirecting stderr in that order, not like in yours. As you can test that your code waits until the say command is complete while my example didn’t. Anyway, the proper way would be using two redirections where you first redirect stdout and then redirect stderr to stdout.

You’re code doesn’t run in the background because stderr is not pointing to /dev/null

do shell script "say 'Hello World!' 2>&1 >/dev/null  &" --wrong redirection

Now we have first defined stdout and then redirect stderr to stdout, which makes them both point to /dev/null

do shell script "say 'Hello World!' >/dev/null 2>&1 &" --correct redirection

But instead of using two redirection, you can write it down shorter getting the same results.

do shell script "say 'Hello World!' &>/dev/null &" --correct redirection

Hi Dj,

I see what you’re saying now. Yes it does not wait until it’s done!

do shell script "(osascript -e 'say \"hello world\"' &>/dev/null &); say \"I'm done\""

I was getting mixed up with the redirection stuff.

Thanks for the explanation,