So I have a script in ruby that obviously uses variables. Part of the script opens an app and runs an automator workflow. There are some variables in my ruby script that I need my workflow to use. Is this possible in anyway?
Are you able to:
a) Execute a command line program from Ruby
b) Save your Automator workflow as an application
If so, you should be able to run the open command, e.g. open test.app --args someArg. Or you could use the automator command, such as echo "someArg" | automator -i - test.app
Note that the entire Automator script will run once for each argument - try having ‘Speak Text’ as your first item to verify this.
To work with all the parameters in one go you need to actually pass just one and then split it up, e.g. open test.app --args "one|two|three|four" then something like
on run input
set myArray to my theSplit(input as string, "|")
set a to item 1 of myArray
set b to item 2 of myArray
set c to item 3 of myArray
set d to item 4 of myArray
display dialog "c is " & c
--do stuff
return str
end run
on theSplit(theString, theDelimiter)
-- save delimiters to restore old settings
set oldDelimiters to AppleScript's text item delimiters
-- set delimiters to delimiter to be used
set AppleScript's text item delimiters to theDelimiter
-- create the array
--set theArray to every text item of theString
set theArray to text items of theString
--display dialog theArray as string
-- restore the old setting
set AppleScript's text item delimiters to oldDelimiters
-- return the result
return theArray
end theSplit
However, the AppleScript only seems to work if it’s not the first action. If you need it as the first action, which you probably do, insert a Run Shell Script first that just passes on the arguments:
for f
do
echo “$f"
done
Yes, it is possible to pass parameters to a ruby script. Here is a nice tutorial:
http://ruby.about.com/od/rubyfeatures/a/argv.htm
Related
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"
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.)
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"
I'm splitting a string using osascript (was working this way, not with bash), and assigning the resulting array to a bash variable, and continuing with my bash script. I'm doing it like so:
tempArrayApplications=$(osascript >/dev/null <<EOF
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to "/"
set theArray to every text item of "$noSplitString"
set AppleScript's text item delimiters to oldDelimiters
return theArray
EOF)
However, the command line returns the error that it went to the end of the file without finding the matching ')'. However, when I don't assign a bash variable to the osascript output, everything works fine, so I know it's not a problem with the AppleScript section. I ran shellcheck, and it doesn't detect any errors, and the other solutions seem to be related to an unclosed quote or unescaped character, but I don't seem to have that problem. Clearly it's due to trying to assign it to a bash variable, but for the life of me I don't know what I'm doing wrong. Thanks for the help.
Have you paused to consider that you're taking a bash variable ($noSplitString); inserting this into an AppleScript that splits the text using / as the delimiter; executing this AppleScript inside a bash command (osascript); then storing its output (which actually gets destroyed) in another bash variable ($tempArrayApplications)...?
My inclination would be to remove the AppleScript altogether (3 out of its 5 lines are redundant, anyway), and create the array from the string within bash.
So, given this:
noSplitString="item 1/item 2/item 3"
Then simply do this:
IFS='/'
tempArrayApplications=($noSplitString)
Now $tempArrayApplications will be an array with three items, starting at index 0 and ending at index 2. You can echo a specific element in the array like this:
echo "${tempArrayApplications[1]}" # "item 2"
IFS is the bash equivalent of the AppleScript text item delimiters. It typically has a default value of ⎵\t\n (where ⎵ indicates a space character). More can be read about it in this article: Bash IFS: its Definition, Viewing it and Modifying it
My team requires an Automator service that will allow us to copy file paths from within OS X Finder such that they always start with "afp://server-name/" instead of "/Volumes/server-name/" BUT ALSO replaces all spaces with "%20".
Right now, we are using the following code, which does replace the first space in a given string, but does not replace all spaces.
on run {input, parameters}
set output to {}
repeat with f in input
set end of output to replace(POSIX path of f, "/Volumes/Brand Design", "afp://nycp-afp01/Brand%20Design")
end repeat
set text item delimiters to linefeed
set the clipboard to (output as text)
end run
on replace(input, search, replace)
set text item delimiters to search
set ti to text items of input
set text item delimiters to replace
ti as text
end replace
Any help you can provide will be HUGELY appreciated; thanx!
A.
to get rid of spaces use your replace handler again Inside itself (last line).
my replace(ti as text, " ","%20")
I'm looking for a way to get ALL the values for a specified key in a plist file.
Indeed, I want to go through the plist file and every time I read the specified key, I put the value in an array for example.
Thanks a lot :)
You can try to access the values with sed. Assuming:
set keyValues to paragraphs of (do shell script "sed -En '/CFBundleIconFile/ {
n
s/.*>([^<]+).*/\\1/
p
}' < " & quoted form of "/Users/John/Desktop/Info.plist")
I'm not sure I understand you fully, but here's an example on how to read all the IODisplayLocation values from the windowserver preferences and create an applescript array.
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to ";"
set theItems to (do shell script "defaults read /Library/Preferences/com.apple.windowserver | grep IODisplayLocation | awk '{print $3}'")
set itemList to (every text item of theItems) as list
set AppleScript's text item delimiters to oldDelimiters
display dialog item 4 of itemList
I want to get the system language of the currently logged in user. The line
set lang to do shell script "defaults read NSGlobalDomain AppleLanguages"
returns an string, which looks like
(
en,
de,
ja,
fr,
es,
it,
pt,
"pt-PT",
nl,
sv,
nb,
da,
fi,
ru,
pl,
"zh-Hans",
"zh-Hant",
ko,
ar,
cs,
hu,
tr
)
returns the users languages, but how can I get the first one of this 'array'? Is there a possibility to parse this as an array an get its first value?
There's a more direct method. Applescript has a command "system info" which returns a lot of useful information about the current user. Try this to see...
return system info
The information that will help you from that is "user locale". So you can get the language easily...
return user locale of (get system info)
Play around with this on different users and see if it gives you what you want.
The thread is really old, but I just had the problem and this comes up pretty high in a Google search. For other readers, I want to add two comments:
There is a difference between the “return user locale of (get system info)” and the “defaults read NSGlobalDomain AppleLanguages” strategies: The first returns the value from the region settings, the latter the value from the language settings (both in “Language & Text”).
Region settings return a language and a region, separated by underscore. Language settings return either just a language or language and region, separated by hyphen. If you use that in other code, make sure, it is tolerant.
The second point: GREPing works, but the simplest code I found is using the Property List suite from System Events:
on get_language()
set lang to do shell script "defaults read NSGlobalDomain AppleLanguages"
tell application "System Events"
set pl to make new property list item with properties {text:lang}
set r to value of pl
end tell
return item 1 of r
end get_language
grep my be faster, but this requires less brain twisting.
Jürgen
You can use awk and grep to prepare the list a little (get rid of indentation, quotes and parentheses), then split the resulting string:
-- a standard split function
to split of aString by sep
local aList, delims
tell AppleScript
set delims to text item delimiters
set text item delimiters to sep
set aList to text items of aString
set text item delimiters to delims
end tell
return aList
end split
-- pipe the output of defaults through a few more commands
set cmd to "defaults read NSGlobalDomain AppleLanguages | awk '{gsub(/[^a-zA-Z-]/,\"\");print}' | grep -v '^$'"
set langs to do shell script cmd
-- get the first item in the list
set lang to item 1 of (split of langs by return)
The shell command gives you a list like:
en
da
ja
fr
de
es
it
pt
pt-PT
nl
sv
nb
fi
ru
pl
zh-Hans
zh-Hant
ko
So item 1 will be en
By now this thread is ancient, but still the most relevant one of all results to my search entry. So I think this may be relevant to others searching for an answer to this question.
Based on what user1635960 wrote, the following “one liner” appears quite simple to me:
set lang to first word of (do shell script "defaults read NSGlobalDomain AppleLanguages")
As my first system language is German, it simply returns de.
Explanation:
do shell script "defaults read NSGlobalDomain AppleLanguages"
returns a list like
"(
\"de-DE\",
\"nl-DE\",
\"en-DE\"
)"
The class word defines a sequence of mainly letters and/or numbers, delimited by one or more of most other characters. So first word of the above list results in de.