Make Shell script to wait until applescript finishes? - shell

I have a shell script which calls an AppleScript. AppleScript runs some automated tests on a software with a given document.
After the AppleScript finishes its execution I am moving the document to some other folder using mv command in my shell script and then I am moving the next document so that AppleScript can run those tests with this new document. But as soon as AppleScript is called it moves the document to another folder without those tests being run on that document.
How can I give a wait in my shell script so that the document is moved only after the AppleScript has finished executing all the tests?
1. mv $file "/path/to/file" (Moving the document to the execution folder)
2. osascript /pathto/applescript.app (it will use this execution folder to run its tests)
3. mv "/path/to/file" /Users/Desktop/tempfolder (moving the document on which the test is completed to a temp folder)
Steps 2 and 3 go one after another without wait, hence the document on which the test is to be run is moved before the test completes.

Normally, shell commands are executed in-sequence. That is, the next statement is not run until the current one is done executing, whether or not it was successful. So if this is the case you can merely write your script one command after another.
I guess that osascript /pathto/applescript.app run some tasks in a different process, and that osascript returns from its own execution while the process doing "what you want" is still running.
What you could do would be to ps -aux | grep applescript.app then get the pid from that, and do a while loop afterward to see when the program cease. But that seem overengineered and you don't know the execution name of the applescript.app.
If I am wrong somewhere please anybody correct me

As Mayerz said, do shell script command is waiting for end of instruction to move to next AppleScript command. In any case, you can also use the "considering application response" bloc. Here is an example with a move in Finder :
set A to ("myVolume:Users:Me:Documents:sample.mov") as alias
set B to ("Users:me:Desktop:") as alias
tell application "Finder"
considering application responses
move A to B
end considering
end tell
display dialog "done"
Similar example with do shell script:
set A to ("myVolume:Users:Me:Documents:sample.mov") as alias
set B to path to desktop
set AU to POSIX path of A
set BU to (POSIX path of B) & "test2.mov"
tell application "Finder"
considering application responses
do shell script "mv " & (quoted form of AU) & " " & (quoted form of BU)
end considering
end tell
display dialog "done"

Related

How to start a .command script from a mac automator app

I'm trying to create a mac "app" using automator that basically calls a .command file to do all the work. The command file will be in the same dir as the .app but i'm falling at the first which is - get the current directory of the .app file thats been clicked to determine the file location of the .command file.
i've tried
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
echo "-- $SCRIPTPATH"
This just returns my users director - basically ~
The app itself is in a dir on the Desktop example: ~/Desktop/foo/my.app
I've also tried
here="`dirname \"$0\"`"
echo "cd-ing to $here"
cd "$here" || exit 1
neither work.
ultimately i need to call my.command to run the command but need to know its actual position - or even relative to the app so that it'll fire. currently i get the error that it can't find the my.command as its not located in the root of my user account (since i wont have control over where it can be placed on the end users machine).
Any pointers on what i can do to solve this much appreciated.
Note: To answer - why am i using an app which has a terminal script to call a .command which is essentially a script - basically because if you do it this way a terminal doesn't actually pop up.. which for this demo is what i need to happen.
As you did not include explicit details of your Automator workflow, saved as an application, I'm presenting the following as an example of how to have and Automator app, e.g. my.app, execute the e.g. my.command script file, that which is located in the same folder as e.g. my.app is.
For the purpose of the example, I created a folder named foo on my Desktop, in which my.app was saved along with the my.command script file.
The Automator application workflow uses a Run AppleScript action to accomplish the goal.
Replace the default code with the following example AppleScript code:
set myCommandFilename to "my.command"
set myAppPathAlias to path to me
tell application "System Events"
set myDirName to POSIX path of container of myAppPathAlias
set myCommandFilePathname to myDirName & "/" & myCommandFilename
set myCommandFilenameExists to exists file myCommandFilePathname
end tell
if myCommandFilenameExists then
try
do shell script myCommandFilePathname's quoted form
on error eStr number eNum
display dialog eStr & " number " & eNum ¬
buttons {"OK"} default button 1 ¬
with title "File I/O Error..." with icon stop
end try
else
display dialog "A necessary file, ' " & myCommandFilePathname & ¬
"', is missing!" buttons {"OK"} default button 1 ¬
with title "Missing File..." with icon stop
end if
Note: Change my.command to the actual filename. The rest of the example AppleScript code should not need to be modified.
If my.app is launched and the my.command script file is not in the same folder as my.app, then an error message will be displayed, e.g.:
If my.app is launched and the my.command script file doesn't have its executable bit set, then this error message will be displayed, e.g.:
Also, if the my.command script file does not exit cleanly, it too will display an error message, e.g.:
The content of the error message will vary based on the content of the e.g. my.command script file, how it's coded and how it fails. This example is worst case scenario in that it lets you know something failed, but not what failed.
Note: The example AppleScript code is just that and does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors.

Run Bash script on selected files in Finder

I have a tiny Bash script that executes ffmpeg and a touch command on an input file. I use this to recompress video files from my camera. I would like to be able to right-click files in Finder and run the script on the select file(s), preferably showing the terminal window while executing and closing when done.
How to do this on macOS?
I think this is what you want. I started Automator by pressing ⌘space and starting to type "Automator", hitting ↩ as soon as it guessed correctly. I then created a "Quick Action" that contains this code:
on run {input, parameters}
repeat with theItem in input
set f to POSIX path of theItem
tell application "Terminal"
activate
tell window 1
do script "echo " & f
end tell
end tell
end repeat
end run
and looks like this:
It basically just echos the filename, but you can put ffmpeg commands in there instead.
Why using finder? Or automator? Or going though loops and hoops just to use the GUI?
You have fully-functional bash shell in MacOS, so save time and hassle with the below one-liner.
Assuming you need to run your script for all *.mpeg files in the folder.
Try this:
ls *mpeg | xargs <your_script_name>
You will see the execution output in the same terminal window.

Applescript run bash script from same directory

I'm trying to build an AppleScript to launch my shell script.
Path structure is as follows
/Users/ryan/myscript/
applescript.scpt
bash.sh
My AppleScript is as follows:
tell application "Terminal"
set folder_path to path to me
set run_cmd to "/bin/bash " & folder_path & "/bash.sh"
do script run_cmd
activate
end tell
Problem is the 'path to me' is not always returning the correct path. When executed using the Mac cd/dvd autoplay behavior folder_path is equal to:
disk:System:Library:CoreServices:SystemUIServer.app:Contents:XPCServices:com.apple.systemuiserver.scriptrunner.xpc:
Is there is a better way of getting the folder path?
If this Script is in a static location, you can do this:
do shell script "/bin/bash" & POSIX path of (path to current user folder) & "myscript/bash.sh"
Path to me refers to the location of the applescript that is running. So if your script is on a disk then it will reference the location on the disk where the script is saved
if it is expected that the shell script will always exist in a folder called "myscripts" that exists in the current user folder then you could use path to current user folder and build out from there
set user_folder to path to current user folder
set folder_path to quoted form of POSIX path of (("" & user_folder & "myscript"))
tell application "Terminal"
activate
set run_cmd to "/bin/bash " & folder_path & "/bash.sh"
do script run_cmd
end tell
Is there a reason why you have to store the shell script in a separate file? Typically, you would put it inline, within the AppleScript code. As far as I know, the “do shell script” command only operates on text, not on a script at a file path. If you give it a variable that contains a path, it will try to run that path as a command. It won’t run the contents of the file as a command.
Here is an example of an AppleScript that runs an inline shell script and puts the results in TextEdit:
property theShellScript : "#!/bin/bash
echo Hello World"
tell application "TextEdit"
activate
set theScriptResult to do shell script theShellScript
make new document
set the text of document 1 to theScriptResult
end tell
… you can of course replace the above shell script with the contents of your own shell script.
If you do need to keep the script in a separate file, the best way to do that is probably to save your AppleScript as an Application, and put the shell script within the Application bundle. “Path to me” is the path of the application that is running the script — not to the script itself — but if you save your AppleScript as an Application, then it runs its own script, and “path to me” works as you originally expected.
Here is an example of an AppleScript that runs a shell script contained within a file that is stored within its own application bundle:
property theApplicationPath : the path to me as text
property theShellScriptPath : theApplicationPath & "Contents:Resources:Scripts:bash.sh"
tell application "TextEdit"
open alias theShellScriptPath
set theShellScript to the text of document 1
set theScriptResult to do shell script theShellScript
make new document
set the text of document 1 to theScriptResult
end tell
With the above script Copy/Pasted into a new document in AppleScript Editor, hold down the Option key and choose File ▶ Save As, and in the Save dialog box, on the File Format pop up menu, choose “Application” and of course give your application a name and click Save. Then in Finder, navigate to where you Saved your application, and 2-finger tap (or right-click) on your application and choose “Show Package Contents.” That opens your application up as a folder, exposing the file system within. Put your shell script file named “bash.sh” inside the folder “Contents/Resources/Scripts” within your application and then close the window that represents your application.
Now when you run your application from anywhere in the file system, it will still be able to find and run its incorporated shell script.

Create a launcher for a node.js script

I'm trying to create a launcher for node.js scripts (so that I can run the scripts by clicking on their file icons instead of launching them from the terminal.) How is this usually done? I'd prefer if I could simply run a script in the terminal by clicking on its icon.
I tried writing a shell script to launch another script in the same folder, but it doesn't show the node.js script's command line output for some reason:
#!/bin/bash
echo -n "Enter a node.js script to run > "
read text
node "$text"
I now know that you're looking for an Ubuntu solution, but in case someone is interested in an OS X solution, here goes:
Open Automator.
Create a new application.
Add an AppleScript action
Paste the following code:
on run {input, parameters}
tell application "Terminal"
repeat with f in input
do script "node " & quoted form of (POSIX path of f)
end repeat
activate
end tell
end run
Save the application.
In Finder, control-click any *.js file and select Open With > Other ..., pick the new application and check 'Always Open With.'
From then on, whenever you open a *.js file, it will open in a new Terminal window that will stay open after node finishes running; add ; exit to the command string above to close automatically (possibly adding read -sn 1 first to wait for a keystroke first.)
i use this to start my node scripts on debian in the terminal
#!/usr/bin/env sh
dir=$(dirname $0)
script="$dir/path_to_your_server.js"
echo "node $script"

How can I convert bash's command substitution and pipe to an Applescript?

I need help converting this simple shell script to an apple script.
The point being because it is to be used in an Automator workflow, and so I need the Terminal window to be open, which cannot be done using a shell script.
The shell script is as follows:
java -classpath `dirname "$1"` `basename "$1" | sed "s/.class//g"`
This gets the location of the file, and then the name of the file, and then strips away the file extension of ".class", and then runs it using the Java command. So for example it would generate the following command:
java -classpath /users/desktop/ filename
I need to convert this command so that it works with Applescript so that I can then see the application run in the Terminal window. It would start like the following:
on run {input, parameters}
tell application "Terminal"
activate
do shell script "java -classpath path/to/ file"
end tell
end run
How can I port the text transformation to Applescript?
The only issue I'm seeing (right now) is to change do shell script to do script. Other than that, you've started it correctly. I'm assuming you want to pass (a) file reference(s) to the shell script. It's fairly simple...
set these_files to (choose file with multiple selections allowed)
repeat with this_file in these_files
tell application "Finder" to if the name extension of this_file is "class" then my do_shell_script(this_file)
end repeat
on do_shell_script(this_file)
tell application "Terminal" to activate --makes 'Terminal' the frontmost application
--'do shell script ...' goes here
--To refer to a file/folder for a 'do shell script', do something like the command below...
--do shell script "mdls -name kMDItemLastUsedDate " & quoted form of the POSIX path of this_file
end do_shell_script
I don't know AppleScript at all, but I suppose you could simply call your existing shell script in the do shell script line, instead of trying to redo the string manipulation in AppleScript.
Note:
It looks like you want to be able to invoke Java classes by click (or drag-n-drop or such). Your method will only work for classes in the anonymous package, i.e. without any package ...; declaration in the beginning of the source code. For others, you might try to find out in which package they are. I have no idea how to do this. Distributable programs should be in jar archives, anyway, where you should be able to start it with java -jar ....)

Resources