How do I include a command line utility in my applescript? - macos

I wrote an applescript that makes use of an external command line script that helps to perform clicks.
Now, if I want to publish my script, what should be my approach to the end users? I mean, should I say to them: "first of all you have to download this CLI utiltity, and put in this folder... then download and run my script!"
This is a newbie question but: is this the only way to do this? or can I include in some way the CLI code in my script/package? If yes how?

If the script is short enough, you can include it in the AppleScript directly:
do shell script "if [ -f /tmp/foo ]; then rm /tmp/foo; fi"
If it's long and/or complex enough that that's unwieldy, you can embed it in the application bundle (I think in the Contents/MacOS subfolder would be the best place), and then execute it from AppleScript like this:
set objectFolder to (path to me) as string
do shell script ((quoted form of POSIX path of (objectFolder)) ¬
& "Contents/MacOS/scriptname")

Related

calling another scripts to run in current script

I'm writing a shell script. what it does is it will create a file by the input that is received from the user. Now, i want to add the feature called "view a file" for my current script. Now, it's unreasonal to retype it again since i've already had a script that helps
I know it's crazy when it is possible to it with normal shell command. I'm actually writing a script that help me to create pages that are generated from the touch command. (this pages had attached date, author name, subjects, and title).
The question is how to call a another script or inhere another script?
Couple of ways to do this. My prefered way is by using source
You can -
Call your other script with the source command (alias is .) like this: source /path/to/script.
Make the other script executable, add the #!/bin/bash line at the top, and the path where the file is to the $PATH environment variable. Then you can call it as a normal command.
Use the bash command to execute it: /bin/bash /path/to/script

Execute a shell command on a file selected in the Finder

I'm a very novice and infrequent applescript experimenter. I've tried for several hours now to learn the individual applescript commands for the following task, but I always run into errors. Perhaps someone much more adept at applescript will find this task easy and quick, and for that I would be very grateful. Here is the task:
I want to be able to manually select a document or file within the finder and then execute the following unix command on that file. I would then store the script under Finder's "Services" menu. The unix command is:
srm -rfv -m path/filename
In my attempts, I assumed that a script that would open Terminal and execute the command would be the way to go, but just couldn't get anything to work. Thank you in advance to any good programmers who can whip out such a script for me.
My tip: Create such services using Automator!
Create a new Service in Automator
Choose "File & Folder" as Input and "Finder"
Add "Run shell script"
Choose "as arguments" as input
Change echo "$f" to your command srm -rfv -m "$f"
Save it as "Safe delete"
From now on, if you select a file inside Finder you will find the option "Safe delete" in the context menu.
Enjoy, Michael / Hamburg
Craig's comment is pertinent, but I am just focus on the script itself, not on the shell command. the script bellow must be saved as Application and each time you drop 1 or more file on its icon, the shell script command will be executed for each file :
on open myFiles
repeat with aFile in myFiles -- repeat loop in case you drop more than 1 file on the icon script
try
do shell script "srm -rfv -m " & (quoted form of POSIX path of aFile)
end try
end repeat
end open
Still make sure that in your shell command 'srm -rfv', the 'v' is necessary because this script will not display any thing ! I don't think so. also I did not display error during remove. what do you want to do with error (like write protect, ...) ?
Update: I missed that the OP wants to create an OS X Service that integrates with Finder. ShooTerKo's answer shows how to do that (and his solution doesn't even require use of AppleScript).
The only potentially interesting thing about this answer is that it demonstrates AppleScript commands to open a file-selection dialog, get the chosen file's POSIX path and run a shell command with it, with some general background information about executing shell commands with do shell script.
Try the following:
# Let the user choose a file via an interactive dialog.
set fileChosen to choose file
# Get the file's POSIX path.
set filePath to POSIX path of fileChosen
# Use the path to synthesize a shell command and execute it.
do shell script "echo srm -rfv -m " & quoted form of filePath
Note:
There's no explicit error handling; if you don't want the script to just fail, you'll have to add error handling (try ... on error ... end try) to handle the case of the user canceling the file selection and the shell command failing (unlikely in this case).
The shell command has echo prepended to it in order to perform a dry run (see its output in Script Editor's Result pane); remove it to perform the actual deletion.
quoted form of is important for ensuring that a string value is included as-is in a shell command (no risk of expansion (interpretation) by the shell).
do shell script will NOT open a Terminal window - it will simply run the shell command hidden and return its stdout output, which is usually what you want. If the shell command signals failure via a non-zero exit code, an error is raised.

Wait for PID to exit using AppleScript

I'm new to AppleScript but I have to recreate a batch file which I have written for Windows in OSX and AppleScript seems the best way to do this. Basically, the script will created by another program dynamically and then executed. The AppleScript simply needs to wait for a process, which I want to identify by its process ID, and display a message if the process is still running after a specific amount of time.
Is this possible, and if so, how?
Thanks in advance
I eventually found a solution to my given problem after searching online a bit more. Here is the AppleScript code I use to check if a process with a given id pid is running
tell application "System Events"
set runningApplications to (unix id of every process)
if (runningApplications contains (pid as integer)) is false then
-- process is not running
else
-- process still running
end if
end tell
This is just a snippet obviously. Personally I have the above the statement in a repeat loop, but this offers a solution to checking a process id (which is the unix id).
Hope this helps others
Here are some things to (hopefully) get you on your way:
shell scripts in terminal, and 'do shell script' command: don't know how well you know Unix, but you definitely want to go there, and
learn basics of bash. with some limitations, you can run shell
scripts via AS through the 'do shell script' command.
writing the script dynamically: osascript and osacompile will probably come in handy. see the man pages. osascript can execute
scripts or script text, and osacompile can (!) compile text into
script form (non-text form), among other things.
script waiting for/watching process: more shell script stuff, or using the Finder (what used to be called the Scriptable Finder!),
that is, the Finder's scripting capabilities (dictionary), like
tell application "Finder" to get name of processes. The shell version (which can be called via the 'do shell script' AS command)
might be "ps ax | grep Safari | grep -v grep | awk '{print $1}'" (taken from
stackoverflow post. I like it because it returns empty string if no
match). Depending on how your main script will run, learn how the
idle handler works in a script application, and how that differs from
using an xcode-built app (if that's the route you go), or just a
script.
displaying a message: 'display dialog' is the super simple method, complete with timeout ("gives up" after n seconds). (Sorry if this is
so basic I just insulted your intelligence :-) )
other: Check out (unless you're already wedded to a script editing environment) Smile. It's my primary script editor.

How To Run This Script More Easily

I have a Ruby script that I wrote that sorts some files in a jumble of directories based on it's file extension. It would be very difficult to sort it using a GUI, and its easier for me to just put the file in the topmost directory and let the sorter do the work.
Problem is, I'm a bit of a noob to unix scripting. What I want to be able to do is be able to run that sorter script from anywhere on my computer, without having to
cd Desktop/Whatever/Foo
ruby sorterscript.rb
just write sortfolders at the commandline and have the program be run.
I've tested the script many times, and it works fine, I just want a bit more convenience.
Bonus: If possible, and not too difficult, it would be even better if I could have the program run, say, every hour automatically.
As far as your first question goes, you need to do couple of things:
Add a shebang line to your script (make it the first line of the script):
#!/usr/bin/ruby (or whatever the path to the Ruby interpreter's executable is, I forget its exact location)
Make the script executable, either via the Finder's "Get Info" context menu, or via the command line, for example:
chmod 755 my_script.rb
Add the directory location of your script to the PATH environment variable to OS X's launchd.conf file, as described here. You need to add this line:
setenv PATH /path/to/my/script:$PATH (substitute the real path to your script)
As far as your bonus question goes, you can use cron to set up a recurring job. I never really do this, but here's Apple's cron man page to get you started.

Run same command on all terminals in mac

Is there a way to run the same command on all the open terminal tabs . I usually log into many servers and want to perform the same command on all of them. Xshell (available on windows only) had this feature where you can run same command on all open terminals , i am wondering if its possible in mac somehow ?
It is most definitely possible. I do it quite often. This solves it:
onall () {
if [[ $1 == "--help" ]]; then
echo "Usage: onall <command>"
return 0
fi
osascript -e "tell application \"Terminal\"
repeat with w in windows
repeat with t in tabs of w
do script \"${1//\"/\\\"}\" in t
end repeat
end repeat
end tell"
}
osascript is the command-line program to run AppleScript code and the -e option tells it to use the following string as the script. The ${1//\"/\\\"} escapes all of the quotes in the command.
You can either declare it as is in your .bash_profile or whatever other file you use or you can take it out of the function, put it into a script, make the script executable and put it somewhere that is always in your PATH.
NOTE 1: The entire command must be in the first argument.
NOTE 2: If you're doing a command with quotes in it, you must escape the quotes.
For example, onall echo "*" will not give the expected results. Instead, use onall "echo \"*\""
iTerm2 can solve this problem.
steps:
split terminal as per your requirement
click on shell -> broadcast input (select broadcast setting as per you requirement)
Screen shot for reference:
Instead of using Terminal for this, use SSH. If it's a command you need to run in a terminal, odds are you're sshing somewhere anyway - eliminate the middle man.
Generate passwordless ssh keypair, put the public key on the remote systems, then from a single shell script you can do something like
for host in host1 host2 host3 ..; do
ssh -i ~/.ssh/my_private_key username#${host} "echo HAXXXXXXXXXXXX | wall"
done
This is a very crude mechanism, but it's lightyears beyond having to physically open a terminal for each command.
I actually know of something that'll do what you want on OSX, but honestly it's such a generically bad idea it would be negligent of me to provide a hyperlink to it.

Resources