Ok! Based on your comments, I would rewrite your question something like this:
How to trick
system("echo %s")
into running AppleScript?I'm trying to push the limits of
system()
to understand why it is important to be careful with its use in C. This sample program is presented in a book on C:#include <stdio.h> #include <stdlib.h> char* now() { return "yyyy-mm-dd"; } int main() { char comment[80]; char cmd[120]; fgets(comment, 80, stdin); sprintf(cmd, "echo '%s %s' >> reports.log", comment, now()); return system(cmd); }
I can "echo out" of the program and execute most bash scripts with the program by typing
' && pwd && '
. Now I want to figure out how to do something similar, but by using AppleScript instead of bash. I’m trying this:' && "osascript -e 'tell application "Terminal"' -e 'do script "foo bar"' -e 'end tell'" && '
The
osascript ... 'end tell'
command works when run directly in the terminal, but it’s not executing properly. I have tried many variations on quotes, etc, to no avail.
Then, my answer would be the following:
To make it easier to debug exactly what command is being run, let’s echo the command to the terminal:
#include <stdio.h>
#include <stdlib.h>
char* now() {
return "yyyy-mm-dd";
}
int main() {
char comment[80];
char cmd[120];
fgets(comment, 80, stdin);
sprintf(cmd, "echo '%s %s' >> reports.log", comment, now());
/* for debugging */
printf("executing %s\n", cmd);
return system(cmd);
}
Now let’s try it out:
$ gcc -c prog.c -o prog
$ ./prog
' && osascript -e 'tell application "Terminal"' -e 'do script "date"' -e 'end tell'" && '
executing echo '' && osascript -e 'tell application "Terminal"' -e 'do script "date"' -e 'end t yyyy-mm-dd' >> reports.log
Huh! It somehow got cut off as end t
instead of end tell'" && '
. Wait, how big is the input buffer? 80 characters? That’s the problem! The AppleScript command you’re trying is syntactically correct, but is too long for the input buffer and is getting chopped off.
Eliminating all whitespace and using a little-known bash feature to embed the newlines, I can just barely squeeze that AppleScript into 77 characters:
'&&osascript -e$'tell application "Terminal"\ndo script "date"\nend tell'&& '
Since the 80-character buffer needs a null-terminator at the end, it really only has room for 79 characters. So with this particular AppleScript command you can run shell commands in terminal up to 6 characters long…
My answer to what I thought was your original question—how to call a multi-line AppleScript from C—remains:
Command-line arguments can have newlines in them. You can run an entire AppleScript from bash like this:
$ osascript -e '
tell application "Terminal"
do script "date"
end tell'
bash pauses waiting for the closing '
, and then passes the whole script as a single argument.
You can do something similar in C, just with a bit more quoting:
#include <stdio.h>
int main() {
system("osascript -e '\n"
"tell application \"Terminal\"\n"
" do script \"date\"\n"
"end tell'\n");
return 0;
}