Take the 2-minute tour ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

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'"
    $CMD
}

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 \"$@\""
}
share|improve this question
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! –  Gordon Davisson Feb 17 '13 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 '13 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. –  Gordon Davisson Mar 21 '13 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 '13 at 8:22
add comment

2 Answers 2

up vote 1 down vote accepted

You can use the run handler to pass arguments:

dialog() {
    osascript -e 'on run args
    try
    tell app "SystemUIServer" to display dialog (item 1 of args)
    end
    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 "")
end
end
activate app (path to frontmost application as text)
answer' | tr '\r' ' ')
[ -z "$answer" ] && exit
share|improve this answer
add comment

Try this;

#!/bin/bash
dialog() {
  DIALOGVAR=$('tell app "System Events" to display dialog "'$@'"')
  CMD=$("osascript -e 'tell application \"System Events\" to activate'"; "osascript -e '$DIALOGVAR'")
  $CMD
  }
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.