0

My Problem

I have an AppleScript script file called script.scpt.

This is the first line of the script where I'm intending to use labeled parameters (AKA named parameters):

on run given foo:fooStr

I open Terminal and attempt to run the script by typing the following:

osascript "/Users/UserName/Library/Mobile Documents/com~apple~ScriptEditor2/Documents/script.scpt" given foo:"bar"

I get the resulting error:

execution error: The foo parameter is missing for run. (-1701)

I have tried every other variation I can think of for supplying the labeled/named parameter to the script within the command line with no success.

My Question

How do I pass labeled/named parameters to an existing AppleScript script file via the command line? Thanks in advance.


Background

I previously had the script using the following line:

on run argv

And then did things the "typical" way by getting values I needed within my script based on their predetermined sequential position when supplied on the command line as such:

set fooStr to item 1 of argv

Where the command line was:

osascript "/Users/UserName/Library/Mobile Documents/com~apple~ScriptEditor2/Documents/script.scpt" "bar"

Art Geigel
  • 1,915
  • 3
  • 22
  • 24
  • You don’t. The `run` handler is not like a user-defined handler - it is an event handler, which takes parameters as a single list. You can load the script and individually call its run handler like that, but not from a shell script. – red_menace Jul 07 '21 at 22:29

2 Answers2

0

Use standard *nix shell conventions and parse any options in the arguments list yourself.

Simple hand-rolled example:

property _syntax : "cmd [-A] [-B VALUE] [-h] [-] [ARG ...]"

on run argv
    -- parse options
    set opt_A to false
    set opt_B to ""
    considering case
        repeat while argv is not {} and argv's first item begins with "-"
            set flag to argv's first item
            set argv to rest of argv
            if flag is "-A" then
                set opt_A to true
            else if flag is "-B" then
                set opt_B to argv's first item
                set argv to rest of argv
            else if flag is "-h" then
                log _syntax
                return
            else if flag is "-" then
                exit repeat
            else
                error "Unknown option: " & flag
            end if
        end repeat
    end considering
    -- do any validation here
    doStuff(opt_A, opt_B, argv)
end run

to doStuff(foo, bar, baz)
    -- do work here
end doStuff

(If your options are particularly complex, or you write a lot of these scripts, you may prefer to use an existing options parser, e.g. NSArgumentDomain of NSUserDefaults via AppleScript-ObjC, or parse command line arguments in File library.)

foo
  • 664
  • 1
  • 4
  • 4
0

The run handler is a little different than a regular user-defined handler - as an event handler, it takes parameters as a single list. You can define it with a labeled parameter, but when something executes the script, standard POSIX conventions for command line arguments are used.

The command line pre-dates labeled parameters by a few decades; it uses option switches instead. You can also implement something like that, but whether that is worth it or not would depend on exactly what you are trying to do.

An alternative to switches would be to call a handler that runs the target after arranging the arguments (a script's run handler would be declared as usual). One way to do this would be to merge an argument record with a default and then pass a list of keys in the desired order, for example:

to runWithArgs given args:argRecord -- run shell script with arguments from merged records
    set defaults to {foo:"foo", bar:"bar", baz:"baz", another:"four"} -- or whatever
    if class of argRecord is not record then set argRecord to {}
    set merged to {foo, bar, baz, another} of (argRecord & defaults) -- the desired keys and order
    set arguments to ""
    repeat with anItem in merged
        set arguments to arguments & space & quoted form of (anItem as text)
    end repeat
    do shell script "echo" & arguments -- osascript, etc
end runWithArgs

runWithArgs given args:{whatever:"no, not this one", another:4, foo:"this is a test"}

An alternative that doesn't use the command line would be to use load script, and call the individual handlers (you wouldn't necessarily need to use a run handler). For example:

set scpt to load script "/path/to/foo.scpt"
tell scpt to run given foo:"bar"
tell scpt to someHandler given someLabel:"whatever"
red_menace
  • 3,162
  • 2
  • 10
  • 18
  • “The run handler is a little different … as an event handler, it takes parameters as a single list.” -- That has nothing to do with `run` being an event handler; it is simply how the original AppleScript engineers chose to pass arguments to that particular handler. The distinction is purely conceptual: “command” handlers receive [action] messages sent from a script; “event” handlers receive [notification] messages sent *to* a script. The actual mechanics are identical either way. (And irrelevant here, as OP asked how to pass labeled arguments to an AppleScript _from the *nix shell_.) – foo Jul 09 '21 at 19:09