I have found a few things on how to run another applescript application but not on giving it an input. On applescript site I found this:
tell application "NonStayOpen"
launch
stringTest("Some example text.")
end tell
Which would be a solution, I just rap the script in a handler and pass my variable. But not matter what I do I can not get the handler to activate.
Ideal Situation
run script that contains the following:
tell application id "com.apple.testhandlerApp"
TestHandler("Hi") --Or if I can get the Open(SomeVar) to work
end tell
which then activates application testhandlerApp containing the script:
on TestHandler(somevar)
set contentText to somevar as string
display dialog contentText
end TestHandler
Giving me a dialog saying "Hi". Reason being is I want to put the first bit of code into automator to runs a complex application that takes a text input. Right now all I get is "Connection is invalid." If I didn't need the input it seems using activate works fine.
There's 2 ways I can think of.
1) Create your "testhandlerApp.app" with the following code. I saved mine on the desktop. You'll notice it has an "on run" handler that accepts an argument list which then runs TestHandler(). The try block of code just prevents an error if you launch the app yourself. Obviously in that case there is no argument list passed and the code errors so the try block prevents that.
NOTE: this method will also work if you save this as a plain script instead of an application.
on run argList
try
class of argList
on error
set argList to {"No arguments were passed!"}
end try
TestHandler(item 1 of argList)
end run
on TestHandler(somevar)
set contentText to somevar as string
display dialog contentText
end TestHandler
Then to call this from another applescript you use the "run script" command as follows.
set appPath to (path to desktop as text) & "testhandlerApp.app"
run script file appPath with parameters {"Hi"}
You can even call it from the command line with something like this...
osascript /path/to/script arg1 arg2
2) Create your "testhandlerApp.app" with the following code. Save this as a "stay open" applescript application by checking the "stay open" checkbox in the save window.
on run
end run
on TestHandler(somevar)
set contentText to somevar as string
display dialog contentText
end TestHandler
Then to call this from another applescript use this...
tell application "testhandlerApp"
TestHandler("Hi")
quit
end tell
Good luck!
This link for AppleScript Language Guide might help. I haven't done what you are asking before- as I am pretty new to AppleScript, but it appears Automator as an on run function that may help. Checkout this link of AppleScript tips -including the on run function.
Related
I want to send a selected group of lines to my current ipython window from a texteditor (It's TextMate in this case, but that's largely irrelevant.) The script uses a bash call so it can accept the variable and then an Applescript call to push the code to the window.
This current script works, but it can only send a single non-nested line at a time. Is there a way to fix this so I can send multiple non-nested lines of code at once?
#!/bin/bash
QUOTED_TEXT=${TM_SELECTED_TEXT//\"/\\\"}
echo "$QUOTED_TEXT"
osascript <<- APPLESCRIPT
tell application "Terminal"
set currentTab to (selected tab of (get first window))
set tabProcs to processes of currentTab
set theProc to (end of tabProcs)
if theProc is not "Python" then
set currentTab to (do script "ipython")
end if
do script "$QUOTED_TEXT \n" in currentTab
end tell
APPLESCRIPT
I don't use either TM or ipython myself so can't provide an immediate answer to your exact problem, but here's some general thoughts on calling AppleScript from Terminal:
Never pass arguments to AS like that: it's a mis-quoting accident just waiting to happen. Wrap your AS code in an on run argv ... end run handler, then append your extra arguments to the osascript command when calling it in bash. osascript will then pass those arguments directly to AppleScript as a list of strings assigned to the argv variable. Safe and simple.
Rather than wrap your AS code in a bash script, just add #!/usr/bin/osascript at the top of your AS code, save it as a plain text file in an appropriate location (e.g. somewhere on your shell's $PATH, such as /usr/local/bin), then do chmod +x /path/to/script to make it executable. This will allow you to run it directly from Terminal.
If you want to access STDIN or environment variables directly within an AppleScript-based shell script, use the AppleScript-ObjC bridge to call NSFileHandle's fileHandleWithStandardInput()'s readDataToEndOfFile() and NSProcessInfo's processInfo()'s environment() respectively. To access ARGV, use an explicit run handler as described above.
By default, osascript automatically writes the value returned by the run handler to STDOUT; alternatively, you can write directly to STDOUT at any time via NSFileHandler (you can put a plain return statement at the end of run handler to ensure it returns nothing else). And osascript automatically writes the results of log commands to STDERR, and sets the return code to non-zero when your script throws an uncaught exception (e.g. use an error ERROR_STRING number ERROR_NUMBER statement to raise an exception directly in your AS code).
(BTW, I wrote a File library not long ago that includes a bunch of very nice handlers for writing AS-based shell scripts. I no longer develop or support it myself; however, various folks have already forked it, so if you do much AS+shell work you may find it a helpful source of AS code to cut-and-paste or even to use as-is.)
So, I am trying to create an app with AppleScript, but when I move my app in a different folder and run it, it always will look at the folder it was in before.
display dialog "Kindle Fire HDX 7" Utility Mac
Please select the action you want to do.
Make sure a Terminal window is OPENED!!!"
buttons {"Connected Devices", "Reboot", "More..."} default button 3
set the button_pressed to the button returned of the result
if the button_pressed is "Connected Devices" then
-- action for 1st button goes here
tell application "Terminal"
VVVV Right here is error
if (count of windows) is not 0 then
do script "cd ~/Desktop/ADB-GUI/Kindle Fire HDX 7" Utility.app/Contents/Resources/minerboyadb/ && ./adb devices"
^^^^ Right here is error
end if
else if the button_pressed is "" then
-- action for 2nd button goes here
else
-- action for 3rd button goes here
end if
Is there a way to fix this? Or is it possible to use Xcode to make an AppleScript app? (Which might work better.)
Your code, as posted as of this writing, won't compile, but to answer the question in general:
POSIX path of (path to me)
will return the POSIX path to the running AppleScript-based application from within it, including a trailing /; e.g.: "/Applications/MyAppleScriptApp.app/"
Aside from that, you should always use quoted form of when adding an argument to a shell-command string for use with do script or do shell script, so as to ensure that it is preserved as-is and doesn't break the overall shell command.
Furthermore, assuming your intent is to simply display/capture the output from a shell command, use do shell script, which runs a shell command hidden and returns its stdout output; e.g.:
set cmdOutput to do shell script "ls"
display alert "Files in current folder" message cmdOutput
I'm trying to write a script that runs both as an app and from the command line using osascript. In both cases, I want to pop up a "help" dialog. In the case of the app, it should pop up when I double click the app. In the case of the command-line launch, I want it to pop up when I run the script without arguments (eg: osascript myScript.scpt) . The attached script does not pop up the dialog properly when I double click the app, but it does work from the command line. If I delete just the argv on the first line, and then remove the -- on the second, thereby emulating the existence of argv, it works fine with a double click. That is, the behavior is radically different when I use the supplied argv than it is when I don't. Is this a bug or am I doing something wrong?
on run argv -- if I remove the argv from this line
-- set argv to [] -- and then comment *in* this line, it works fine
getDefaults() -- when I double-click the app
if (count of argv) = 0 then
displayHelp() -- doesn't display on double click when I use "on run argv"
else
processFromCommandLine(argv)
end if
end run
on displayHelp()
display dialog "Help!"
end displayHelp
on processFromCommandLine(argv)
end processFromCommandLine
The Script App is quitting with error when you double-click because arg is not assigned to a class you can count, but then you try and get its count. Just wrap it in a try block instead.
on run argv
getDefaults()
try
get (count of argv)
processFromCommandLine(argv)
on error
displayHelp()
end try
end run
There's almost certainly a better way, but this works:
on run argv
-- Display help.
if argv = current application or ¬
argv's class ≠ list or argv's length = 0 then
display dialog "Help!"
return
end if
-- Do stuff.
end run
It looks like the direct parameter for the run handler is set to...
current application when a script is launched as an application.
me when run from Script Editor.
I am pretty new to AppleScript. I need a script that opens 3 iTerm tabs and executes 3 command line programs respectively. The first program terminates, while the last 2 run indeterminately.
Here is what I have:
tell application "iTerm"
activate
set next to (make new terminal)
tell next
activate current session
launch session "Default Session"
tell the last session
set name to "vagrant-db"
write text "cd ~/Workspace/vagrant-db; vagrant up"
end tell
launch session "Default Session"
tell the last session
set name to "next/core"
write text "cd ~/Workspace/next"
write text "/usr/local/bin/sbt \"project core\" \"run\""
end tell
launch session "Default Session"
tell the last session
set name to "next/web"
write text "cd ~/Workspace/next"
write text "/usr/local/bin/sbt \"project web\" \"~re-start\""
end tell
end tell
end tell
Problem is I need to wait for the first command line operation to end (vagrant booting up) before issuing the second and third. Is there a way to do it?
Not sure if it is possible, but maybe using "do shell script" command from applescript instead, e.g.
set response to do shell script "ls"
will return the contents of the root folder.
Another way (but a very ugly one) is to use 'delay'. E.g.
delay 5
Will delay for 5 seconds
solved with something like
--first program exec
set a to 0
repeat until (a = 1)
if (text of current session contains "ready") then
set a to 1
end if
end repeat
--second program exec
--third program exec
Rusty's answer worked for me. I'm adding this answer to provide detail requested by fusio (sorry, I'd rather have provided this as comment, but comments require more reputation points than adding a new answer).
Rusty's answer requires already being in the context of talking to the current window.
on wait_for(str)
tell application "iTerm"
tell current window
set a to 0
repeat until (a = 1)
if (text of current session contains str) then
set a to 1
end if
end repeat
end tell
end tell
end wait_for
Then, in your code, call:
my wait_for("Provisioners marked to run always will still run.")
The above argument occurs later than "ready".
This is still plenty ugly, but it works.
In AppleScript how do you use a handler from another script?
I have tried this
set test to (load script "/Users/username/Desktop/test.scpt")
test()
here is test.scpt on the desktop
display dialog "test"
when running the first script I get
error "«script» doesn’t understand the test message." number -1708 from «script» to «class test»
You need to wrap the code you want to call in a handler:
test.scpt:
on doTest()
display dialog "test"
end doTest
Then to execute it:
set test to (load script "/Users/username/Desktop/test.scpt")
tell test to doTest()