Posts RSS Comments RSS 48 Posts and 155 Comments till now

Archive for the 'Applescript' Category

Check your current IP address with AppleScript

This script will get your current “real world” IP address. It’s very useful when you’re using a router giving out internal addresses and you need to know the address the world is seeing for you. It will also store that IP address so you can have this script run on a schedule and only report if your IP address has changed.

Click here to download the script

[codesyntax lang=”applescript” lines=”no”]
property theIP : “”
set TheResult to (do shell script “curl -f http://checkip.dyndns.org”)
set Olddelim to AppleScript’s text item delimiters
try
set AppleScript’s text item delimiters to “Current IP Address: ”
set LongIP to item 2 of every text item of TheResult as text
set AppleScript’s text item delimiters to “”
set stopPoint to (offset of “< " in LongIP) set myip to characters 1 through (stopPoint - 1) of LongIP as text if theIP is "" then set theIP to myip display dialog "Your IP is : " & myip end if if myip is not equal to theIP then display dialog "Your IP is : " & myip set theIP to myip end if set AppleScript's text item delimiters to Olddelim on error set AppleScript's text item delimiters to Olddelim end try [/codesyntax]

Delete printers using AppleScript

I recently had a request for a script that would delete printers from a lab build. The user wanted to make one system build for all of his labs with all of the printers installed. Then, just run a script to select the correct printer for that lab and delete the others. Here’s the script I came up with. With this script you can choose more then one printer if that is more appropriate.


--get the name of every printer
tell application "Printer Setup Utility"
set theList to the name of every printer as list
end tell

--present the list to choose the printer from
choose from list theList with title "Lab Printer" with prompt "Pick the correct printer for this lab" with multiple selections allowed
set theItem to the result as list

--loop through the list and delete any printer not in the list theItem
repeat with x from 1 to the count of theList
if theItem does not contain (item x of theList) then
do shell script "lpadmin -x " & (item x of theList)
end if
end repeat

Pinging a server using AppleScript

I’ve recently had a machine that suddenly seems to lose it’s network connection. I can’t figure out why but it always comes back after a reboot. The big problem with this is it’s my backup server and having that off the network is not good. So, I came up with an AppleScript that runs each hour to see if we’re still talking to the world. If not then I reboot the machine.

Here’s the basic script:


try
set thePing to do shell script "/sbin/ping -o -c 5 www.google.com"
on error
delay 60
try
set thePing to do shell script "/sbin/ping -o -c 5 www.google.com"
on error
do shell script "/sbin/shutdown -r now"
end try
end try

Breaking down the script

set thePing to do shell script "/sbin/ping -o -c 5 www.google.com"

This executes the command line version of ping to see if we’re on the network. The “-o” means quit pinging as soon as we get a reply. Don’t want to flood Google with pings! The “-c 5” says only send 5 pings at the most.

If there is no response for what ever reason it throws an error. So the “on error” part of the script catches that and tells the script to delay itself for 60 seconds and then continue.

After 60 seconds we try again. If we get an error again the we tell the machine to restart itself using “shutdown -r”.

I run this script as a System cron job, running once an hour. By running as system I don’t have to include any passwords and if it needs to shutdown most likely no active processes can get in the way. I use Cronnix to set up my cron jobs. Saving the job as “ping.scpt” the cron job would look like this:

/usr/bin/osascript /path/to/ping.scpt

Using AppleScript to set the default printer

Here’s a simple little script that you can use to reset which printer is listed as default. You can set it up as a Login Item and have it run every time you log in to reset the default printer.

Get the name of the printer you want from Printer Setup Utility. You want the actual name displayed in the Printer Setup Window.

In AppleScript the term “current printer” refers to the currently selected printer, which is always the current default printer.

After you have the name place in this script, replacing the words “Epson Inkjet Printer”.

Download the compiled script here:
Default Printer Script

[codesyntax lang=”applescript” lines=”no”]
tell application “Printer Setup Utility”
set the_printer to the current printer
set the_name to the name of the_printer
if the_name is not “Epson Inkjet Printer” then
set the_count to the count of printers
repeat with x from 1 to the_count
if the name of printer x is “Epson Inkjet Printer” then
set the current printer to printer x
end if
end repeat
end if
quit
end tell
[/codesyntax]

The script gets the name of the current default printer. Then it loops through all the printers in the list looking for the name of the one you want. When the script comes to that name it sets it to be the current printer. Calling Printer Setup Utility in a script always launches it so I put a “quit” statement at the end so we don’t have Printer Setup Utility running afterwards.

Using Applescript to kill off a process

I use AppleScript to clean up some temp spaces on my lab machines. It’s easy to use and gives me most of what I need without a lot of shell programming. However, to do some of the cleaning I have to call up the Finder. That’s fine if the machine is already logged in but what if it isn’t? My cleanup script runs around 2 AM each morning when no ones around and no one’s logged in.

The issue with that is since the script runs as root it launchs the Finder as root. And leaves it running as root. So if you were to go to one of those machines in the morning you’d see the Finder running underneath the Login window. If you log in as a normal user it doesn’t restart the Finder, just leaves it running as Root. So, anybody could come along, log in and have complete root privileges to the entire system until they log out. Can you say security issue?

So, I have a small script that I keep around for just such an occasion. It does a search and destroy for the Finder process ID and kills it at the end of the script so we aren’t leaving root hanging around.

[codesyntax lang=”applescript” lines=”no”]
set app_name to “Finder”
set the_pid to (do shell script “ps ax | grep ” & (quoted form of app_name) & ” | grep -v grep | awk ‘{print $1}'”)
if the_pid is not “” then do shell script (“kill -9 ” & the_pid)
[/codesyntax]

First we set the variable “app_name” to the name of the process we want to kill.

Next we set the variable “the_pid” to the process ID of that process. It takes a little fancy shell scripting and text manipulation to get that.

Finally, if we did find it then we send the “kill -9” command with the process ID to kill it off. Using “kill -9” is basically saying “Die and no back talk”.

Now you’ve successfully killed off the Finder running as root and closed the hole. You can use this script to kill off other processes as well.

Adding and deleting login items using AppleScript

It’s a fairly simple process to script adding and deleting login items using applescript. You can save these scripts as applications and send them out to users. Then they can run it themselves and add or remove a login item. You can have applications open on login or volumes mount on login.

Adding a login item

For adding a login item we’ll use the example of mounting a remote volume. I usually find that it works best to actually mount the item first and then add the login item. For this example we’ll assume we’re connecting to an SMB share named “home” on a Windows server.

[codesyntax lang=”applescript” lines=”no”]
mount volume “smb://server.example.com/home”
tell application “Finder”
--check to see if the volume mounted
if disk “home” exists then
display dialog “Success”
--this “tell” statement makes the actual login item
tell application “System Events”
make login item at end with properties {path:”/Volumes/home”, kind:volume}
end tell
else
--if it doesn’t work let the user know
display dialog “Oops! This problem happened:” & return & errmsg
end if
end tell
[/codesyntax]

So, in the example above we mount the server share first. Then, we check to see if it’s actually there. If so we tell the user we’ve succeeded with a dialog box and make the login item. If not we let them know there was a problem and display the error message so they can tell tech support.

Notice the “kind” section of that line. You need to tell it what you’re adding (a volume, an application, etc.).

Deleting a login item

Deleting a login item is even easier.

[codesyntax lang=”applescript” lines=”no”]
tell application “System Events”
--Find out what login items we have
get the name of every login item
--see if the item we want exists. If so then delete it
if login item “home” exists then
delete login item “home”
else
display dialog “That login item doesn’t exist”
end if
end tell
[/codesyntax]

We check to see what login items we have. If the one we want to delete exists we go ahead and nuke it.

Creating Internet-enabled Disk images

What is an Internet-enabled disk image?

Basically, an internet-enabled disk image is a standard .dmg file with one small change. When it is downloaded using a browser it will automatically decompress the image, put the application or folder on the desktop, unmount and remove the disk image file. This way users don’t have to deal with downloading an image, double-clicking on it, dragging out the files, etc. It’s all done in one fell swoop.

How do I make my images internet-enabled?

First you have to create a disk image. There are lots of tutorials out there on how to do this (it’s quite easy). There are also a few applications that will do it for you, such as DropDMG. Apple even has an Automator action that will do this for you.

Once you’ve created your disk image fire up Terminal and use the hdiutil utility. The option we want is internet-enable -yes.

So, if I have a disk image on our desktop named myapp.dmg I would use the following syntax:

hdiutil internet-enable -yes /Path/to/image/myapp.dmg

Since I find myself creating these files a lot for installer packages I’ve found an easier way. Paste this text into Script Editor and save it as an application. It will create a droplet. Then just drag and drop your disk image file on the droplet and it will be instantly internet-enabled!

[codesyntax lang=”applescript” lines=”no”]
on open theFile
tell application “Finder”
set theNamePath to (theFile as text)
set theName to the name of the file theNamePath
end tell
set thePath to the quoted form of the POSIX path of theFile
try
do shell script “/usr/bin/hdiutil internet-enable -yes ” & thePath
display dialog “The disk image ” & (ASCII character 34) & theName & (ASCII character 34)¬
& ” has been successfully internet-enabled!”
on error errmsg
display dialog “Oops! This error occured: ” & return & return & ¬
errmsg buttons {“OK”} default button 1
end try
end open
[/codesyntax]

Trapping error codes in AppleScript

If you use AppleScript you know sometimes when you try to do things such as mount a remote volume things can go wrong. Then you get a error message with number telling (hopefully) what went wrong. But you might not want that error message to show up. Maybe if that error happens you want your script to do something. If so then you have to trap that error first.

To catch an error you need to wrap the part of your script that is doing the action in a try statement. So, if I wanted to open a file I might use something like this:

[codesyntax lang=”applescript” lines=”no”]
try
tell application “Finder”
open file “Hard Drive:Users:joe:oops.txt”
end tell
on error errmsg
end try
[/codesyntax]

The script trys to run that command and if there is a problem the error message gets put into the variable errmsg. Then we can handle that error another way, perhaps with a dialog box.

[codesyntax lang=”applescript” lines=”no”]
try
tell application “Finder”
open file “Hard Drive:Users:joe:oops.txt”
end tell
on error errmsg
display dialog errmsg buttons {“Oops”}
end try
[/codesyntax]

That works great for generic errors but what if we know the error code of a specific error, such as the file doesn’t exist ,which happens to be -1728. Then we can add the number property to our on error trap and do something specific for that error.

[codesyntax lang=”applescript” lines=”no”]
try
tell application “Finder”
open file “Hard Drive:Users:joe:oops.txt”
end tell
on error errmsg number errNum
if errNum is -1728 then
display dialog “Hey, that file doesn’t exist!” buttons {“Doh!”}
else
display dialog errmsg buttons {“Oops”}
end try
[/codesyntax]

Now we can give the user specific feedback on certain errors and just display the error message for all other errors.

Creating printers in Terminal

Using the Printer Setup Utility in OS X is a very easy and simple way to create printers on a Mac. But occasionally you might have need to create printers at the command line. For example, you might want to create printers on remote machines that only have shell access. Or you might want to add the ability to create printers to a login script or a script that runs after a machine is re-imaged.

Well, the command to do this is lpadmin. lpadmin is used mainly to set up network printers. It’s the command line utility for CUPS, the underlying printing architecture of OS X. As usual you can type man lpadmin to get all the gory details. In this post I’m going to cover how to create a printer and how to delete one using Terminal and lpd.

Creating a new printer

The syntax to create a new printer is:

/usr/sbin/lpadmin -p "name of printer" -E -v lpd://"printer IP or DNS"/"queue name" -P "path to PPD file" -D "description"

The name of the printer is whatever you want the user to see, such as “color laser printer”. Just remember if your name has spaces in it you’ll either need to escape the spaces or quote the name. Also, the name cannot contain any non-printable characters (ex. % $ &). The description field, however, can. If you use the description field that is the name that appears in Printer Setup Utility. If you don’t then the name given in the - p flag will be the name.

All of the standard PPD files on a Mac are kept in /Library/Printers/PPD/Contents/Resources/en.lprog/. The actual PPD file will be contained in a .gz file. You just need to point to that file.

So, for our example we’ll set up a printer with the following attributes:

Name: Color_Laser
Type: HP Color Laser 4700
Print server: print.example.com
print queue: color_laser
description: Color Laser (Front Office)

So our command in the Terminal would be this:

usr/sbin/lpadmin -p Color_Laser -E -v lpd://print.example.com/color_laser -P /Library/Printers/PPDs/Contents/Resources/en.lproj/HP\ Color\ LaserJet\ 4700.gz -D "Color Laser (Front Office)"

Note that I quoted the “Color Laser (Front Office)” part to get around spaces in the name. That’s the name that appears in Printer Setup Utility.

Deleting a Printer

Deleting a printer is much easier. All you need is the name.

The syntax to delete a printer is:

/usr/sbin/lpadmin -x "name of printer"

If I wanted to delete the printer I just created all I would need to do is this:

/usr/sbin/lpadmin -x "Color Laser"

Note: The name you’re deleting is the name you gave it in the - p flag, not the description. So putting “Color Laser (Front Office)” in this would not work.

If you’ve forgotten what names you gave the printers open up a web browser on your machine and enter “http://127.0.0.1:631/printers”. That will take you to the configuration page for CUPS, which will list the printers by name.

Creating printers in AppleScript

You can wrap all of these commands up in an AppleScript and send it to users so they can install printers with just a click. Just wrap the commands in a do shell script command.

The one gotcha is because you are using quotes in the Terminal command AND you have to quote to actual command in AppleScript you have to escape the internal quotes by putting a “\” before each quote. You also have to escape and “escapes” you had in the original command.

To compare, here is the original command:

/usr/sbin/lpadmin -p "Color_Laser" -E -v lpd://print.example.com/color_laser -P /Library/Printers/PPDs/Contents/Resources/en.lproj/HP\ Color\ LaserJet\ 4700.gz -D "Color Laser (Front Office)"

And here is the command with the “do shell script” command in AppleScript:

[codesyntax lang=”applescript” lines=”no”]do shell script “/usr/sbin/lpadmin -p Color_Laser -E -v lpd://print.example.com/color_laser -P /Library/Printers/PPDs/Contents/Resources/en.lproj/HP\\ Color\\ LaserJet\\ 4700.gz -D \”Color Laser (Front Office)\””[/codesyntax]

Finding an image’s color space using AppleScript

I just had a need to write a quick script that told me what the color space of an image was (RGB, CMYK, Gray, etc.). So obviously I turned to AppleScript. AppleScript has a nice Scripting Addition called Image Events that can read lots of different information about an image. You can get all the details on the Image Events addition as well as some good examples here.

The one problem I found with Image Events was that it gagged whenever it looked at a grayscale image. No idea why. But, after doing some more research I found that Image Events is based on a UNIX command line tool named sips. Using sips and the AppleScript do shell script command I was able to get the information I needed.

For my immediate purposes I just wanted a script I could run, select a file and get the color information. So that’s what this script does.

[codesyntax lang=”applescript” lines=”no”]
set theFile to (quoted form of the POSIX path of (choose file))
set theColorSpace to (do shell script “sips -g space ” & theFile)
set oldDelims to AppleScript’s text item delimiters
try
set AppleScript’s text item delimiters to “:”
set theColor to text item 2 of theColorSpace as text
set AppleScript’s text item delimiters to oldDelims
on error
set AppleScript’s text item delimiters to oldDelims
end try
display dialog “The color space is: ” & theColor[/codesyntax]

Notice I had to set the file path to the POSIX path of the file. The POSIX path is the actual Unix style path name (ex. /Users/joe/image.jpg). I also had to use the quoted form part of AppleScript to deal with any spaces that might be in the file names. Running this will give you a dialog box with the name of the color space for this file.

Since Image Events can get lots of other bits of information and it’s easier to manipulate then having to parse. So, I combined AppleScript and Automator to make a Finder plug-in. I developed this Automator script to display the image’s size in pixels, resolution, color space and width in picas. It’s being used by a publisher here to quickly check sizes of images to make sure they meet certain requirements. I expect I’ll be adding things and tweaking it as I go.

Click on Image Info Automator workflow to download the workflow. Save it out as a Finder plug-in to use with any selected images.

« Prev - Next »