I'm trying to create a short alias for creating System dialogs from the Terminal. I tried to create a Bash function (since an alias didn't seem to take arguments) and add it to my .bash_profile, but it's failing me.

My latest attempt is:

dialog() {
    DIALOGVAR='tell app "system events" to display dialog "'$@'"'
    CMD="osascript -e 'tell app \"system events\" to activate' -e '$DIALOGVAR'"

But when I execute it via the Terminal, I get

0:1: syntax error: A unknown token can’t go here. (-2740)

Even though echo'ing the CMD variable gives me a properly formatted command:

osascript -e 'tell app "system events" to activate' -e 'tell app "system events" to display dialog "foo bar"'

Perhaps I'm doing something wrong, perhaps there's an easier way to achieve this. All I'm trying to do is to create an easy to execute command that displays dialogs.

EDIT: Alternative attempt didn't lead to anything either. This one works for arguments without spaces, but fails for multiple arguments.

sysdialog() {
    osascript -e "tell app \"system events\" to activate" -e "tell app \"system events\" to display dialog \"$@\""
  • 2
    Part of the problem is coming from storing the command in a variable before executing it; see BashFAQ 050: I'm trying to put a command in a variable, but the complex cases always fail! Feb 17, 2013 at 16:03
  • 1
    And the the problem with the second approach also has its root in the intricacies of Bash’s argument parsing: "$@" expands to a list of several word arguments, which is not what you want. Use "$*" instead, which expands to a single word argument. See the BashWiki articles Arguments and Quotes. @GordonDavisson, care to turn your comment into an answer?
    – kopischke
    Mar 21, 2013 at 0:14
  • @kopischke: Actually, I don't think I have anything to add to @Lauri Ranta's answer (which I've already voted for) -- she includes the $* trick, and also includes a run handler trick (which makes it more robust about special characters in the message) that I didn't think of. Mar 21, 2013 at 1:25
  • @GordonDavisson I agree Lauri’s answer is neat, but it does not explain why OP’s approaches are failing (literal vs. syntactical quoting, word splitting on parameter expansion of "$*" vs. "$@"), which you pointed out.
    – kopischke
    Mar 21, 2013 at 8:22

2 Answers 2


You can use the run handler to pass arguments:

dialog() {
    osascript -e 'on run args
    tell app "SystemUIServer" to display dialog (item 1 of args)
    activate app (path to frontmost application as text)
    end' "$1"

If you want to call it like dialog a b (instead of dialog 'a b'), change $1 to $*.

System Events quits automatically when it is not used, and there is a small delay when it is opened, so telling it to display the dialog would sometimes be slower.

Without the try block there would be an error if the user presses a cancel button. Without activate the previously focused window wouldn't get focus back when the dialog is closed.

You can use something like this to display text dialogs:

answer=$(osascript -e 'try
tell app "SystemUIServer"
set answer to text returned of (display dialog "" default answer "")
activate app (path to frontmost application as text)
answer' | tr '\r' ' ')
[ -z "$answer" ] && exit

Try this;

dialog() {
  DIALOGVAR=$('tell app "System Events" to display dialog "'$@'"')
  CMD=$("osascript -e 'tell application \"System Events\" to activate'"; "osascript -e '$DIALOGVAR'")

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .