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.
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.
Long time no see. 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.
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.
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.
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:
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.
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 . . .
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.
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