Search Results for Learning terminal

learning the Terminal: Part Three

Screen Shot 2016-07-02 at 15.24.53
It’s been a while since we last posted about Terminal tips and tricks, but a question popped up today about how to discover what tools are available on the command line.

Most of the tools you use in Terminal are located in /usr/bin, and we can use a nifty little tool from there to find out about all its friends. The whatis tool gives you a one-liner description of what a tool does. If it looks interesting, you can find out more about the tool by typing man and the tool’s name on the command line to see its help manual.

On my current machine, there’s over 1000 tools in /usr/bin, and life is just too short to go through them all doing whatis on each and every one, so we’ll combine a bit of command line power with some AppleScript magic, and produce a nice, easy-to-scroll output of all the summaries like the one in the screenshot above.

Copy the script below (or from my pastebin here) and paste it into the Script Editor (/Applications/Utilities/Script Editor.app). Click the ▶︎ button to run it.

This script took about 1m 30 seconds to run on my machine, but you only need to run it once then save the output. Browse or search through it at your own convenience. 🙂

The script will choose TextWrangler for display if you have it installed; if not, it’ll default to TextEdit. The display is much nicer in TextWrangler, but if you’re stuck with TextEdit, turning off ‘Check Spelling’ in TextEdit will aid readability.

# start 

(* 

This script produces a summary of all the CLI tools 

in /usr/bin and displays it in a text document 

*)

set noDocsList to {}

on extractDescription(aText)

repeat with i from 1 to count of items in aText

set this_item to item i of aText

if this_item contains "NNAAMMEE" then

set r to item (i + 1) of aText

try

set o to offset of "" in r

set short_r to text (o + 1) thru -1 of r

set r to short_r

end try

return r

end if

end repeat

end extractDescription

set theDescriptions to return & return & "**********************************" & return & "SUMMARY OF CLI TOOLS (Version 2)" & return & "**********************************" & return & return & return

tell application "System Events"

set theItems to name of every file of folder "bin" of folder "usr" of startup disk

end tell

repeat with i from 1 to count of theItems

set this_item to item i of theItems

set n_item to length of this_item

try

set what_is to do shell script "whatis " & this_item

if text 1 thru n_item of what_is is this_item and what_is does not contain "nothing appropriate" then

set theDescriptions to theDescriptions & return & what_is & return

else

try

set getMan to paragraphs of (do shell script "man " & this_item)

set desc to extractDescription(getMan)

set what_is to this_item & tab & tab & tab & tab & desc

set theDescriptions to theDescriptions & return & what_is & return

on error

set end of my noDocsList to this_item & return

end try

end if

end try

end repeat

set theApp to "TextEdit"

tell application "Finder"

if exists POSIX file "/Applications/TextWrangler.app" then

set theApp to "TextWrangler"

end if

end tell

set theDescriptions to theDescriptions & return & return & return & "The following tools do not have any documentation: " & return & return & noDocsList

tell application theApp

activate

make new document

set front document's text to my theDescriptions

end tell

# EOF 


learning the Terminal – Part Two



In the last post, we learned how to see all the contents of a folder – invisible and visible files – in the Terminal. However, most of us prefer working in the GUI, so this post is going to show you how to work a bit of Terminal magic to easily turn on and off your invisible files and folders in Finder and the desktop.

Open Terminal, and type or copy/paste the following to the command prompt:

defaults write com.apple.finder AppleShowAllFiles TRUE; killall Finder

(note that all commands in these posts should always be assumed to be case-sensitive).

Press Return.

Now switch out of Terminal and have a look at Finder or your desktop. You should see some ‘hidden’ files now in a sort of greyed-out 50% opacity (files like .DS_Store). If you can’t see such files, go back and check that you typed or copied the entire command correctly.

Assuming you can now see your invisible files in Finder, switch back to Terminal. Press the up arrow key on your keyboard. Notice that the last command you typed reappears.

That’s a handy trick to remember. You can move between your previous commands with the up arrow and down arrow keys to save time re-typing or modifying commands.

In this case, we want to use the last command again, but we also want to modify it. Use the left arrow key to move the cursor back to “True” and then use delete to remove “True”. Leave the cursor where the letter ‘T” was and type FALSE. Make sure the semi-colon ; is still there.

Press Return — you don’t need to move the cursor to the end of the line as you would with a word processor. You can hit Return no matter where the cursor is in the command line and it will execute (or try to) whatever is typed on the whole of the command line.

Now, if you switch back to Finder or the desktop, you should see that all your hidden files have disappeared again.

OK, now that we have tested these commands to check that they work, let’s do something a bit more useful with them.

Switch back to Terminal. Type

^FALSE^TRUE

and press Return.

Wow! Did you see what just happened? You substituted the word “FALSE” from the last command with the word “TRUE” and executed the entire command. In other words, you just made your hidden files visible again! Go and look at the desktop and you’ll see that your invisible files just returned. Try it again. Switch back to Finder and type

^TRUE^FALSE

to replace the word “TRUE” in the last command with the word “FALSE”. Hit Return to execute it.

Using the pattern ^error^correction is a great way to both correct commands you type incorrectly and to run two commands one after the other that have only one term or option different.

Back in Terminal, hit the up arrow to bring the last command back onto the command line. This time, I want you to hit control-A on your keyboard. Notice that this brings the cursor to the start of the command line, which is what we want as we’re going to type in a new command before the “defaults…” part.

With the cursor at the beginning of the line, type

echo

and a space. Then type a double quotation mark right next to the ‘d’ of ‘defaults, so the beginning part looks like this

echo “defaults…

(the ellipsis or ‘…’ is used here just to show that the command continues and should not be in your actual command line)

On the keyboard, press control-E.

This takes the cursor to the end of the command line (remember: control-A to go to the start, control-E to go to the end).

Type another double-quotation mark right after the word ‘Finder’ so the ending looks like this

… ; killall Finder”

Now hit the spacebar once, and type a double right angle-bracket

>>

Hit the spacebar again and type

.bash_profile

The entire command should look like this:

echo “defaults write com.apple.finder AppleShowAllFiles FALSE; killall Finder” >> .bash_profile

Now press Return. Type

^FALSE^TRUE

and press Return one more time.


What did we just do?
To see what you did, type

emacs .bash_profile

As you can see, after testing those two commands on the command line, we’ve now sent them to the .bash_profile file, saving us the job of typing them out again (and possibly making an error when we do so). However, we can’t leave the commands like that – if we do, then they will run every time we log into the Terminal. Rather, we want to use these commands to define functions, just like we did last time with ‘show’ and ‘up’.

To do that, press control-L on the keyboard, then use the down arrow key to bring the cursor to the beginning of the first line with a ‘defaults’ command on it.

Press Return. Press the up arrow once, then type

function hide_all

Press Return and in the new line created type

{

Use the down arrow key to move the cursor down to the line below the “Defaults…FALSE” line and press Return.

In the new line created type

}

Then press Return. Type

function show_all

Press Return and type

{

Use the down arrow key to move the cursor below the “Defaults…TRUE” command. (If you can’t go below the last typed line, then on the keyboard press control-E to move the cursor to the end of the line, the press Return).

Then type

}

Check that the whole thing looks like this:




Once you’re satisfied, hold down the control key while pressing first the x and then c keys. Press y when prompted to confirm the save. You should be returned to the command line. Type

exit

to logout. Then press command-W and command-N to close and reopen Terminal.


What did we do this time?
We just made some new, easy-to-remember commands to show and hide our hidden files in Finder and the desktop. On the way, we learned how to append commands to files using the >> function, as well as how to move the cursor to the beginning and end of a line using ‘control-A’ and ‘control-E’ respectively. We also learned how to recall previous commands on the command line using the arrow keys and how to correct or modify previous commands using the ^error^correction pattern.
Wow, you’ve come a long way in two short tutorials!

To test out what you just did, type

show_all

then press Return.

Switch to Finder and there’s all your hidden files! To make them invisible again, switch back to Terminal and type

hide_all

then Return.

From now on, whenever you want to see your hidden files, just use the show_all command in Terminal. Hide them again with hide_all. 😀



SUMMARY
control-A – places the cursor at the beginning of the command line (also works in emacs editor)
control-E – places the cursor at the end of the command line (also works in emacs editor)
control-L – on the command line, this clears the screen (equivalent to the ‘clear’ command); in emacs, this places the caret inside the editor allowing you to edit (=insert point)

up & down keyboard arrows – moves through history of commands

^error^correction – replaces the term after the first ^ with the term given after the second ^ in the previous command, then executes the entire command

echo – sends the following string or command to the specified file (if no file is specified, the string will output back to your terminal screen. In other words, if you type echo hello, the Terminal will print “Hello” on the next line; hence the term ‘echo’! )


Related Posts:

learning the Terminal – Part One
learning the Terminal – Part Three
how to change all Desktop backgrounds
Fasttasks – a utility for ten common terminal tasks

learning the Terminal – Part One



This is the first in a series of planned tutorials for anyone who wants to find out what Terminal can do and how they can use it to increase the usability of their computer. Unlike other Terminal tutorials, I’m going to assume that you’re not interested in giving up the desktop for the command line to do things like move and copy files that you can do more easily in Finder. Rather, I’m only going to focus on those things that it’s generally more difficult (or impossible!) to do in the GUI than it is in Terminal.

Let’s get started. Open Spotlight (try the hotkey command + spacebar or click the spy glass in the top right corner) , then type term and press Return.

When Terminal opens, the first thing you may want to do is make the text a bit easier to see in the Terminal window.

Hold down command-shift-+ to increase the size. Try it a couple of times till the text is a comfortable size. If you overshoot, just use command- – (minus key) to reduce text size.

Now you’re sitting comfortably in your Terminal window, let’s learn our first spell. Actually, we’re not going to learn one so much as make our own!

In order to do that, we want to open a hidden file and edit it. In Terminal, type

emacs .bash_profile

(There’s a space after ’emacs’, and, don’t forget that . dot right before the ‘b’)

What you see after this screen may vary depending on whether .bash_profile has any pre-existing content or not. If there is anything in the file already, ignore it and use the arrow key to move the cursor to a clean line at the bottom. If the file is empty, then just start typing. The first line we want to type is

function show

Now press Return and enter a single, left curly bracket

{

Press Return again and type (or copy and paste) this:

ls –alF

There’s a space between the ‘s’ and the dash, and all the letters are lowercase except the ‘F’, which must be uppercase.

Press Return and provide the closing curly bracket

}

It should look like the area inside the orange rectangle:




Now hold down the control key on your keyboard while you first press x and then c. Notice at the bottom of the screen you get a ‘save’ warning.

Press the y key on your keyboard, and you should find yourself returned back to the Terminal prompt.

Type exit at the prompt to logout of the Terminal, and then on the keyboard press Command-W to close the window, and Command-N to open a new Terminal session.

What did we just do?
We defined and saved a new Terminal command called show which we can now use whenever we enter Terminal to easily see all the files and folders – including all the hidden ones – in any given directory. To see what we just did, type show at the command line. You should get an output that is formatted something like this:



As you can see I’ve annotated the screenshot to show some of the features that the show command gives us. First of all, notice the file and folder names that begin with a . dot. These are your hidden files and folders (Remember: they are usually hidden for a reason, so don’t go messing with them unless you know what you’re doing!). The show command also helps us distinguish between files and folders by appending a / slash to the end of folder names. Although not shown here, you may also see some names with an * at the end. That means it’s an executable file — in other words, its purpose is to run some programme or command.

The show command is very useful for seeing exactly what is in a folder, but of course we need to know how to move between folders in order to see anything other than our own home directory.

Suppose I want to have a look in that folder called ‘Shared’. Then what I do is I type

cd Sh

then press the tab key on the keyboard. The rest of the name is filled in for me by Terminal:

cd Shared/

The tab key is a very useful trick for moving around in Terminal when you are faced with long names. Generally, you only have to type in enough to make the file or folder name unique and hitting tab will complete the rest of the name for you. However, if I only type

cd S

and then press tab, nothing happens. Terminal can’t complete the name because there’s more than one choice. However, if I press tab again, Terminal will give me a list of the all names that begin with S:

cd S

pressing tab twice gives:

cd S
Shared/ SnowLpd/

Now I can see all the options, and how much I have to type to make a unique choice. In this case, I only have to type either ‘cd Sh’ or ‘cd Sn’ to allow Terminal to know which one I want when I press the tab key. Pressing Return after the tab completion will take me to the folder.

Try it with a folder from your own list.

After changing to a new folder, perhaps your screen is getting a bit messy. Let’s clean it up before doing show again. On the keyboard, press control-L to get a clear screen (notice that all your previous commands and outputs are still available if you scroll up!).

Now type show again to see your files and folders, pick a folder (if there is one), and type cd plus the first few letters of the name. Fill it out with the tab key and then press Return.

Again, type show to find out what’s inside. You can keep going deeper into the directory tree by using cd and show on any folders you find.

The last thing we need to know for today is how to go back up the tree, or to move back to the parent folder. Again we’re going to use the ‘cd’ command, but this time you don’t need to type any names. Just a space and then two dots

cd ..

(don’t forget there’s a space between the ‘d’ and the two dots). This will always take you to the parent folder of the folder you’re currently in, all the way up to your hard disk’s parent directory. If you want, you can make a new up command (just like we made show) as a shortcut for ‘cd ..’. Have a look at the smallest of the screenshots above and see if you can do it. 🙂

So now you know how to move around and see all the hidden and un-hidden contents of your drive, go and explore and get yourself used to these first basic commands.

When you’ve finished with your Terminal session, type exit and press Return. You can then close the window and go back to GUI land!

SUMMARY
. at the beginning of a name means ‘hidden’
/ at the end of a name means ‘Folder’
* at the end of a name means ‘executable file’

cd – move in to that folder
cd .. – move back to the parent folder
emacs – opens the Terminal textfile editor
show – shows a complete list of a directory, including hidden files

control-L – clears the Terminal screen
tab – will try to complete file or folder names
tab (twice) – will offer choices

Related Posts:
learning the Terminal – Part Two
learning the Terminal – Part Three

how to reveal hidden users


With malware big in the news again, and evidence that at least one malware variant that targets macOS creates hidden users on the victim’s system, here’s a timely tip on how to check for unwelcome guests.

For this tip, we’re going to use the Terminal, which you can find in the /Applications/Utilities folder. If you’re not a frequent visitor to the land of the command line, you might want to see my 3-part series “Learning the Terminal”.

Regardless, the first thing we’re going to do in Terminal is about the simplest command you’ll ever type: w. Yep, type a single ‘w’ at the prompt and press return.





The w utility is a very quick way to see who’s currently logged on to your system and to ensure that there’s no surprises. You should see a couple of entries for yourself: one as ‘console’ and one as ‘s***’. The first represents a login through the usual Desktop GUI login window; the second is there because you just logged into Terminal. Anybody else logged in either via the command line (like a potential remote user) or the GUI will show up here. Notice that on my machine, there’s another user called ‘Developer’ who hasn’t logged in using the GUI, but is logged in via a command line interface. Note that ‘w’ returns the full user name, not the short one.

While the w utility will tell you if a hidden user is currently logged on, what if there’s a hidden user that isn’t active at the particular time you check? To look for those, we have a couple of options. First, we can use the dscl utility to list all users, and you might be surprised at how many there are:

dscl . -list /Users

Look to the end of that list where the names that don’t begin with an underscore start. ‘Daemon’, ‘Nobody’, ‘Root’ and ‘Guest’ are all standard system accounts, as are all those entries that begin with an underscore. Don’t worry about those. However, aside from those, you should only see names that you recognise. To make things a little easier, we can add another command to the dscl command to filter that list. Try this

dscl . -list /Users | grep -vE ‘_|root|nobody|daemon|Guest’

That should now only return the names of real users. There shouldn’t be any names in there you don’t recognise. In my example, I know the last three, but the first one ‘dev’ isn’t familiar to me. Note that unlike ‘w’, this command returns short user names, and that ‘dev’ looks very much like it’s the same account as ‘Developer’ that I saw earlier.




However, what we have so far is a list of users, not a list of hidden users. To see specifically if any accounts are hidden, we need a longer command:

defaults read /Library/Preferences/com.apple.loginwindow

Normally, when there are no hidden users, this will return the contents of a property list file that may look something like this:

{
GuestEnabled = 1;
OptimizerLastRunForBuild = 31898816;
OptimizerLastRunForSystem = 168494592;
SHOWFULLNAME = 1;
lastUser = loggedIn;
lastUserName = imackim;
}




That tells us that there’s no hidden users on this mac. How so? Because if there were it would return something very different, like this:





We can see not only the list of hidden users, but also that the preference for hiding users has been set to ‘1’ (in plist syntax, ‘1’ means true and ‘0’ means false). Note again that unlike the dscl command above, this returns the account’s full name, not the short user name.

If we’d like to ‘unhide’ that user, so the account appears in the login window GUI and in System Preferences’ ‘Users & Groups’ pane, we’ll need admin privileges. To do that, cut and paste the following into Terminal:

sudo defaults write /Library/Preferences/com.apple.loginwindow Hide500Users -bool NO

Supply an admin user password at the prompt and hit ‘return’, but type slowly as the display doesn’t register your key presses, which makes it easy to fat finger your password.



For the more advanced
We can save ourselves some typing by putting much of this into a script so that we can run it whenever we want. If you’re not familiar with how to create and use bash scripts, take a look here.

Our script will basically do the same as all the commands we listed above (except changing the prefs for Hide500Users) in one fell swoop, and there’s a couple of little twists that I’ll leave as an exercise for the reader to figure out. To save on the typing, you can copy the whole script from my pastebin here.



The script’s output is illustrated in the shot at the top of this post.

Enjoy! 🙂

Script Debugger 6

This product review by Phil Stokes first appeared on Applehelpwriter.com, July 2016.

SCRIPT DEBUGGER 6 – Late Night Software’s solution to the pains of AppleScripting
Available from Late Night Software
Rating: 9/10

Introduction
It feels like cheating. When you’ve spent pretty much your entire AppleScripting life behind the wheel of Apple’s austere Script Editor application, taking Script Debugger 6 out for a 20-day spin feels like someone’s let you in on a secret you’re not supposed to know. Hurdles you’ve taught yourself to clear – through considerable effort, frustration and no small amount of bloody-minded tenacity – are removed before you get to them; obstacles you’ve habitually steered around or avoided have disappeared, and dark holes of AppleScript mystery appear, in the light shone on them by SD6, to be not the menacing entities you once feared but new friends that offer ways to do things faster and more effectively. The secret that Script Debugger seems to lay bare is that AppleScripting doesn’t have to be as painful as we’ve been conditioned to believe. And that does feel like a cheat. The reward of surviving a trial-by-AppleScript to produce something that actually works and works reliably, that solves a problem you once had and now, magically, do not, is what makes AppleScripting quintessentially AppleScripting, isn’t it? The difficulty, surely, is part of the fun! If that’s true, then Script Debugger 6 will force you to find a different, and more productive, kind of joy in your AppleScripting work.

But wait a minute. Script Debugger has been around for a long time, pretty much as long as AppleScript itself, and existing users will surely say “we could have told you all that years ago!” True, and I did in fact run trials of Script Debugger 4 and Script Debugger 5 without being much impressed, let alone having any kind of epiphany. The reason for that is that Script Debugger has always had its own barriers to entry: there is an investment of both time and money which anyone other than a professional scripter can easily balk at. SD4 and SD5 would run you to $199 for a single-user license for starters, and if you didn’t sit down and thoroughly explore Script Debugger’s feature-laden interface, you ran the very real risk of not only wasting your money but also being overwhelmed by yet more dark AppleScript mystery. My view had always been that there was little point in investing the time it would take to get any benefit out of the software when I was unwilling to accept the price point. If, as I’d oft-heard many other scripters say, it was well worth the money, then I assumed the value must be for those that needed features I didn’t. There just didn’t seem to be $200-worth of things wrong with Apple’s free Script Editor to justify my investing either the time or money in getting to know and buying Script Debugger. My trials of SD4 and SD5 didn’t get much further than a couple of launches fiddling around a bit and deciding it wasn’t for me.

In June this year, Script Debugger’s developers, Late Night Software, released SD6 and the most interesting feature to this non-professional but regular scripter wasn’t any of the things we’ll discuss below, but the price point: a permanent 50% reduction to $99 for a single user license. That’s still no small amount of money. It’s more expensive than almost all the other software I own: Affinity Designer, Scrivener, Camtasia, Carbon Copy Cloner, Little Snitch, 1Password are all cheaper. The one exception I have is Coda (also $99 at the time I bought it). OK, I thought, so there is a precedent. I use Coda a lot for editing and creating html and javascript documents. I also use it to manage my AWS server uploads. It’s well worth the $99 I spent on it. So there’s a challenge: if SD6 could convince me it had enough compelling features that would be as useful to my AppleScripting as Coda is to my web-related tasks, then I’d be willing to buy. But first, I’d have to invest the time getting to know it. A 20-day trial, you say? Should be plenty, right?

Ah-huh. Here’s what happened.

Getting to Know SD6
If you’ve been scripting in Apple’s Script Editor for any length of time, then the experience of moving from that spartan window to Script Debugger’s feature-laden, multi-paned, multi-faceted interface is somewhat reminiscent of those disaster movies where some guy who can fly a Cessna is suddenly thrust into the cockpit of a 747. You are definitely going to want to RTFM! with this one.

Accordingly, I spent most of the first couple of days of my trial checking out the tutorial videos on the developer’s website. In my trials of SD4 and SD5, I’d come to the conclusion that just clicking around and trying to figure things out on my own as you can do with most apps was not going to work. Watching the videos while trialling SD6 revealed a lot about both the features that were new to me and how to take advantage of some I thought I already understood. There’s so much packed into this interface that you really are saving yourself a lot of time and trouble by letting the developers show you around and explain how it all works.

Since the videos are essential viewing, I’ll only skim the surface in this quick orientation to give you a feel for what’s on offer. There is also comprehensive internal Help viewer documentation for more info on all the features. The interface has two primary modes, Standard and Debug, and what you’ll see is subtly different depending on which one you’re in.

SD Shot 1 SD Shot 2

In Debug mode, you’ll see a whole array of new buttons in the toolbar, and the gutter is also populated by grey, yellow and red code coverage dots of various sizes which indicate how often each line was called when you ran the script. The gutter is also the place where you can set, edit and delete breakpoints – lines at which you can halt the script in mid-execution to examine the values of variables (more on this below). The Results & Variables tab on the right adds a call stack view and a breakpoint inspector in Debug mode.

In both Standard and Debug mode, you get the options to view line numbers, fold code, wrap text and create multiple vertical split views by clicking various little buttons scattered around the main editor view. You can also create horizontal split views, but if you have line-wrapping enabled you will need to go to the Edit menu in the menu bar to enable this as the button in the horizontal scroll bar will be hidden from view. One missing feature here is the option to create split views showing different scripts. That would be particularly useful with horizontal splits for making side-by-side comparisons of two versions of the same script in much the same way as can be done in Xcode’s IDE.

Other features in the main window common to both modes include the Event Log (bottom) and the Results and the Variables Tab. The Event Log and the Results panes will be familiar to users of Apple’s Script Editor in the sense that they serve a similar function to the Results and Replies panes you’ll find there, albeit in SD6 you do get some richer information and a few little neat tricks you can do with them (try double-clicking any entry in SD6’s Event Log, for example), but the main difference – and benefit – for new users is the Variables pane. Here you get to see the value of all the variables in the script, either as it completes or at any point along the way if you use Debug mode to stop the script in mid-flow with a breakpoint. The upshot is you can now say goodbye to using the “log” command, a long, in-grained habit I was pleased to find I lost almost without noticing.

The third and lowest pane you see here is the Expressions pane. This is a powerful tool for advanced users that you can learn about in the debugging tutorial video. By the way, don’t shy away from watching the Advanced Debugging video tutorial either because that contains some crucial information about what happens when you save scripts with debugging mode on that you really do not want to miss.

Aside from the Variables pane, the other primary feature you are going to make a lot of use of is the Inspectors tab (available in both modes from the toolbar, rightmost button). Clicking that opens a suite of tools that are going to transform any new AppleScripting challenge you face from a wild groping in the dark to a quick and easy path to a solution.

I’ll start at the bottom with the live Explorer view that shows you the state of the elements and properties of any app you’re targeting in your script.

Creating a tell block will produce a live view of that app’s state in the Explorer pane while your cursor is in that block. If you move your cursor down your script and hit different tell blocks, the Explorer will update as you do. As you can see from the following screenshot, I haven’t even compiled let alone run this script yet. However, SD6 is already showing me the state of System Events and giving me deep insight into what elements and properties are available and what their values are. If you’ve ever wasted half an afternoon trying to discover GUI properties to control some unscriptable app, you’ll rapidly appreciate how much easier this would make the task.

SD Shot 3

Using the Explorer, I also created the following script without writing a single line of code. I merely browsed through the Explorer window for the Finder, and dragged out the URL property of the document I wanted to target:

SD Shot 6

Sitting above the Explorer pane are the Paste Tell and Paste Clipping inspectors. You can drag any of the items from these directly into your script and the appropriate code will be inserted for you. Combined, these three tools give you access to quick bits of code that really turn AppleScripting into something we never expected it could be: in a word, painless.

There’s a whole lot more to discover in the interface that I haven’t mentioned here (remember the videos…), but we can’t leave this quick tour without discussing the Dictionary viewer. The what? Yes, you know, that thing that Apple’s Script Editor has that is so painful to use you almost never bother with it and go searching on MacScripter for answers instead. Well, forget about that. All the things that that doesn’t do for you are done for you by SD6’s Dictionary viewer. When scripting an application for the first time, you’ll find the object model’s graphical view a great aid in getting an overview of how the app is structured and how to target the objects you want. The Dictionary itself gives you all the information you need in one place, including examples of how and where a command is used. The viewer lets you jump around from dictionary to dictionary, app to app as you please. The same live Explorer view mentioned above is also available in the Dictionary viewer, which is useful when you really want to explore deep into some app’s elements and properties and need a larger view to play with.

SD Shot 4

SD Shot 5

Getting to Work
Sometime around day 5 or 6, I started working on some projects for a small community I’m involved in. In particular, this community was in need of a script that would allow them to see when certain files on the system had been updated, as well as a different script that would summarise the functions available on the command line. A third task involved producing a script that could create a USB Installer of the operating system itself. These all seemed like great opportunities to put SD6 through its paces and to see just how much of a difference doing this kind of work in Script Debugger rather than Apple’s Script Editor would be.

With the first task, my main job was to rewrite an existing script in a way that would make it easier to maintain and to add a few extra functions. Both SD6’s code folding and line numbers came in handy here due to the script’s length and the number of embedded handlers. The real bonus though was my first opportunity to try out Debug mode. At one point, I kept seeing a misplaced tab spacing in the displayed output, and it was impossible to find out what was causing the problem in Apple’s Script Editor. Littering the script with logging calls narrowed it down to one of two places, but I still couldn’t see where the problem was being generated since those places were within a repeat loop. Some runs through the loop went successfully, but clearly some did not. Using SD6 I was able to examine the value of a variable within the loop on each run. That allowed me to identify the precise point where the unexpected result was being produced and to move forward with finding a solution to the bug (credit here to my friends on the AppleScript Users mailing list, who nailed the real culprit).

SD Shot 12

My second scripting task involved trying to compile a short summary of all the command line tools available on the system (you can get the full script here). The most interesting thing about this script, from a script editing point-of-view, was that the execution time is lengthy. This led me to discover something about Script Debugger I hadn’t hitherto realised. It executes scripts more slowly than Apple’s Script Editor. The reasons for this are somewhat technical, but boil down to the fact that all that extra feedback you get in the interface bears the cost of increasing the number of Apple Events being sent and received. Script Debugger will take noticebly longer to execute a script when in Debug mode, understandably enough, because it actually has to do quite a bit of work injecting code into the script to obtain the values that it reports back. It’s faster in Standard mode, but still not as fast as Apple’s Script Editor. While performance in execution isn’t critical when developing a script, it’s worth keeping in mind for two reasons. First, you might think a script is not working well because it’s taking longer than you expect. If that’s the case, run it in Apple’s Script Editor to confirm. Second, if speed of execution is important to you or to a particular script you deploy, you might want to develop your scripts in Script Debugger but remember to use Script Editor as your default tool for running them. Having said that, I can’t think of a single script I have on my machine where the difference in speed would really make any practical difference to me.

Something else I discovered during this project was that SD6’s timer (located in the toolbar) should be treated with a bit of caution. The timer will sometimes indicate a script took 10 seconds, even though I can barely count to five before it completes. On other occasions, it might be out by only 3 to 5 seconds on a 60 second script. I’m not sure what use the timer is, in a practical sense, so I don’t see its inaccuracy as of any great importance. Again, something to note, but hardly a deal-breaker.

My third task was to produce a script that would provide an interface to a command line tool with particularly tricky syntax. Rather than having users trying to figure out a complex Terminal command, the script’s aim was to prompt the user for choices by selecting things in the Finder and then to construct and execute the appropriate command for them without the user having to go anywhere near the Terminal. Primarily, I had to ensure that no matter what items the user picked in the Finder, the script would either reject the choices or create a syntactically correct command. That meant I had to be able to examine how the command was shaping up as the script proceeded through various stages. The Variables view and breakpoints made this a doddle, and I was able to easily test all the various “gotchas” by stepping through the appropriate lines of the script one at a time.

As it happened, two of these scripts ended up with me using some AppleScript-ObjectiveC (ASObjC) commands. If you’re unfamiliar with this, it’s a bridge between AppleScript and the Cocoa APIs that are used by programmers in regular Apple apps. Trying to use ASObjC in Apple’s Script Editor is, to put it plainly, a nightmare I don’t want to ever have to revisit. It’s so painful in fact, that I have for years deliberately avoided even trying to use the scripting bridge. That’s a shame because having Cocoa APIs available to AppleScript is a huge, huge win for both scripters and script users. It’s hard to overestimate just how much more you can do with AppleScript once you have the power of Cocoa at your fingertips. Alas, although this ability has been around for a few years and has been getting increasingly more powerful along the way, you could never really claim that it has been at your “fingertips” if you’re using Apple’s Script Editor. The main barrier to entry has always been figuring out the peculiar bastard syntax of ASObjC – it’s neither AppleScript nor is it Objective C, and although I’m conversant with both, I’m still none the wiser about how to construct ASObjC commands.

However, SD6 takes the pain out of this so effectively I was incorporating ASObjC into my projects without a second thought – and without any need to do any extra ‘learning’ of ASObjC’s peculiar syntactic rules. This is achieved through a combination of code completion and built-in code clippings (aka ‘snippets’). I’ll start with the clippings.

There are several ways to access these, but the easiest is probably from the Clippings menu in the menubar.

SD Clippings

Functions like ‘trim whitespace’ are very useful for, say, when you get something back from a ‘do shell script’ that has extra line endings. The joy here is that the ASObjC clippings couldn’t be simpler to use. Choose the clipping from the menu and compile the script without filling in any of the placeholders (that causes SD6 to accept the default placeholder names). You’ll see all the following is inserted automatically for you, without the need for you to write a single line of code:

SD Shot 7

SD Shot 8

In the case of trim whitespace, you can see that you need to create a variable ‘sourceString’ that contains the text you want to trim before the API call to NSString. And that’s all you actually have to write to get the power of Cocoa’s stringByTrimmingCharactersInSet API within your AppleScript. Everything else is done for you. Check it out:

SD Shot 9

Now, the Cocoa API library is vast and no editor could possibly include clippings for all of them. To ameliorate this, SD6 takes a similar approach to Xcode by making the APIs available to you by using live code completion. In SD6, you activate that by pressing the esc key (just as you execute the largely useless text completion feature in Apple’s Script Editor).

SD Shot 10

SD Shot 11

A couple of words of warning are due here. First, note that code completion for Cocoa APIs won’t occur until you’ve already imported a framework and compiled it. You’ll find that including statements like use AppleScript version “2.5” will affect what choices you see differently from use AppleScript version “2.4” – anything defined in 2.5 or later won’t be shown if you’re using 2.4, for example. It’s also worth reviewing the entry for ‘Code Completion’ in the Help docs to understand some of the many conditions that affect what you might see. Second, I’ve had some patchy responses when invoking code completion with the esc key. Occasionally, I’ll not get any response at all. The few times this has happened to me, recompiling or removing and replacing the framework declarations seem to have kicked things back into life again. I haven’t looked into this deeply enough yet to write up a reproducible bug report, and maybe I’m just “doing it wrong”, but when an interface doesn’t behave in a way that a user expects, something warrants further investigation or clarification. I could not find anything in the documentation that explained the unexpected behaviour I saw.

Developing scripts for others means that at some point you are likely to want to bundle libraries or other resources like icons with your script. This is now much easier with the bundle format and you can include and manage any dependencies directly within Script Debugger’s interface. SD6 allows you to declare your own bundle identifier in its General preferences window and to code sign both in the save dialog or from a dedicated bundle resources pane in the main window. Another heads up for the unwary user, though: when you click through the code-signing confirmation dialog in SD6’s initial release version, you may experience the spinning beachball / coloured pin wheel effect. No need to panic – the application isn’t crashing, it’s just blocking the main thread as the code-signing process goes on behind the scenes. This is a bug I’ve already reported and which the developers say will be fixed in a future update.

Coming to the end
My 20 days flew by, and there’s plenty more to discuss. By the time I was nearing the end of my trial I’d learned about a few things that were mysterious to me at the beginning. One of those is that Preferences are a complicated thing in SD6. With most software, you do most if not all of your preference setting in a dedicated Preferences panel. In SD6, the comprehensive Preferences panel sure handles more customisation options than most apps will ever offer you, but there’s even more. Some preferences or customisations can be made by creating your own Script Templates (something I didn’t get around to exploring), and others are set – as they are in Apple’s Script Editor – by setting up the interface the way you want it and then choosing Window > Save Default Script Size & State from the menu bar. If you are looking to make sure things like line numbers and text wrapping are always on, then it’s the latter that you want. Don’t waste time hunting around in the Preferences panes looking for those like I did. Of course, remembering that the Help documentation is (unusually) pretty comprehensive is worth keeping in mind, and if you get stuck, there’s a helpful support forum on the developer’s website.

Speaking of Preferences, I’m personally a fan of dark themes in my editors. I prefer coloured text on a dark almost black background and have all my editors (Xcode, Coda, TextWrangler and even the Terminal) set up this way. If you’re like me, then, you’re going to be a bit disappointed that there’s no choice of ‘themes’ or ‘skins’ in Script Debugger. You can play with the text, background and highlight colourings, but the amount of work involved to produce a readable combination given the complex “pretty printing” of AppleScript’s compiler is something of a chore I haven’t dared face yet.

Only very late in my trial did I come to discover one of SD6’s most useful features, which is the ‘Open Quickly’ function. If you’re familiar with Xcode you’ll know it has a similarly named function and, indeed, both it and SD6 share the same keyboard shortcut. However, they do different things, and what SD6’s does is far more valuable, at least to me. SD6’s feature is more akin to a restricted version of a similar feature in TextWrangler whereby you can search for all documents on your machine that contain a given search term. I’ve never made much use of that in TextWrangler, and I don’t even use Xcode’s differently-acting but samey-sounding “open quickly” function that much either; however, the function in SD6 is awesome for two reasons. One, if you’re anything like me, you’ve got hundreds if not thousands of scripts littered all over your mac. I try to keep most of mine in one place, but they are forever breaking free. The problem this creates is that I’m often working on some new script and finding I need some bit of code I wrote once before, but where it is and in what script I wrote it, I’ve no idea. Prior to using SD6 that meant I’d often go on a long, fruitless and frustrating search trying to figure out which script had the code in it. Now, those days are over. SD6’s ‘open quickly’ will show you all the scripts that contain the code you’re looking for. Secondly, and even better, it’s fast too. We guess it’s using a dedicated mdfind query because the speed at which it achieves this is almost instantaneous and really quite impressive.

And there we are. My 20 days were up and I hadn’t even got into things like trace execution, temporary breakpoints, Show Manifest, the many Search options, looking up definitions of terms, the Mini Script Debugger window, unit testing, leaks and much more.

SD Shot 13

This brings me to the question of trial length. As a developer myself who uses trials to encourage sales, I’m always fascinated by the thinking of developers who choose non-standard trial lengths. Myself, I go with a 30-day trial simply because it was the convention in pre-App Store days. Since then, I see developers plumping for all sorts of odd choices (the worst, I think is some two-bit text editor that offers 2 continuous hours.., but I digress). In SD6’s case, I’m not sure why 20 days is offered, rather than the usual 30. On the one hand, in my view, it isn’t enough to explore all SD6 has to offer precisely because SD6 has so much to offer. On the other, if the aim of a trial is to engage a user enough to convince them they would be better off with the software than without it, well OK, that happened to be enough in my case. But I’ll let you (and the developers, actually) into a little secret: I’d been looking for a better script editor for years, I’d even tried writing my own, and once I saw the new price point, it was going to be difficult to convince me NOT to buy, unless the software failed in some major regard. I went into the trial with the express purpose of doing this review; it took me the whole 20 days to do it (and a few more), and I’m still not all the way through SD6’s feature set. I applaud the developers for dropping the price barrier, but really, I can’t see what advantage a 20-day trial has for them that a 30-day trial wouldn’t. Giving trial users an extra 10 days to find their comfort level and be convinced by the impressive feature-set SD6 has to offer just seems like good business sense to me.



Summary
The result of my trial was that I unhesitatingly bought a license. I don’t think I’ve ever come across a piece of software with so much attention to detail. I haven’t even covered half of what I discovered SD6 can do in this review, and I’m reasonably sure that I haven’t discovered everything that SD6 can do. But this isn’t bloated software weighed down by feature creep. Every feature I’ve looked at answers a concrete need. It’s clear that SD6 is a labour of love by people that actually eat their own dog food – these guys are AppleScripters that know what AppleScripters need because they need it themselves.

Should you buy SD6? I can’t tell you whether you’ll get a good return on your $99 because it depends entirely on how much scripting you do and how much time and effort you want to invest in doing more AppleScripting. I can tell you based on my own experience that if you are a habitual scripter, you’re going to find SD6 an utterly transformative piece of software so long as you’re willing to put in the time as well as the money to learn how best to exploit it. The difference between scripting in Apple’s Script Editor and scripting in SD6 is like the difference between driving along a bumpy road in a 25-year old truck with knackered suspension and cruising down the highway in a state-of-the-art limo that just rolled off the production line. There’s just no comparison in comfort level.

Top of the Class:
Debugging, Application explorer, Dictionary viewer, Code clippings, ASObjC integration, ’Open Quickly’…and a long list of other features that offer relief to pretty much all of AppleScript’s major headaches. No more bumpy road.

Could try harder:
Code-signing blocks the main thread, albeit briefly.
A lack of themes or skins in the Preferences.
Code completion’s lights are on, but it’s not clear that there’s always someone at home.
Horizontal split views would be more useful if they could show different scripts for comparison.
A short-trial time doesn’t give fence-sitters enough chance to get hooked on such a feature-rich application. What harm would another 10-days do anyone?

Get used to it:
Script execution is slower than Apple’s Script Editor.
Timer is not a reliable guide to run time.
$99 is still more than people who are not actively developing and distributing AppleScripts are likely to want to pay. How about an SD Lite, guys? 😉

Read:
More product reviews by Phil Stokes…
AppleScriptObjC In Script Debugger 6

Watch:
Easiest way to GUI Script
Using Cocoa in AppleScript
Using Handlers Pt1
AppleScriptObjC Code Completion In Script Debugger 6

getting to grips with AppleScript

Wall and paper stencil

Learning AppleScript is probably the second most productive thing you can do (the first is learning the Terminal) to improve your Mac experience. You know all those utilities that you see in the Mac App Store, on MacUpdate and so on, with developers charging anything from 99 cents to $20? Well, many of those are just doing simple jobs that you can actually script yourself for free with a little learning of OS X’s unique scripting language (and, indeed, some of those apps have been built in exactly this way).

To keep this post short and practical, I’m going to leave aside the wider discussion of what AppleScript is (and isn’t), what it can (and can’t) do and all manner of other interesting but theoretical things, and instead give you a taste of what you can do with it. I’ll give you some references at the end where you can find out more and learn everything you need.

Let’s get straight to it. Open up the AppleScript Editor by opening the Spotlight search bar and typing Apples. Hit ‘return’ and you’ll be faced with a new editor window. Let’s type something in it.

tell application "Finder"
display dialog "What's your name?" default answer "" with icon note
set myName to the text returned of the result
delay 0.5
display dialog "Hi there, " & myName & "! Welcome to AppleScript!" with icon note
end tell

You could just copy and paste this into the editor, but I’m going to recommend that you don’t. There’s a good reason to take the tedious route and type it in yourself. Like learning a human language, learning a computer language requires using it, and using it repetitively. As you type in the language, you’ll get a feel for its syntax that you won’t get if you just copy and paste. And, unlike a real human language, learning a computer language’s syntax is pretty much the whole battle of mastering it.

After you’ve finished typing, press ‘Command-K’ on the keyboard. If you typed everything correctly, you see the script change into a multi-colored jamboree, like this:

applescript

If you weren’t so lucky, examine what you typed against what’s on the page here. Part of the frustration of any computer language is rooting out typos! Eventually, you get a feel for it and start to learn where to look first, based on the error messages you see. For now, you’ll have to peck and hunt (if you get really fed up, you can always go the cut-and-paste route!).

Assuming you’ve got your script to compile, now it’s time to run it and see what it does. Hit ‘Command-R’ (you can of course use the icons in the toolbar for compiling and running, too) and you should get this:

what's your name?

So go ahead, type your name!

OK, you’re getting the idea. Let’s try something different. Press Control-N to open up a clean editor window and enter this:

say "What's your name?" using "Vicki"
display dialog "My name is " default answer ""
set myName to the text returned of the result
say "His name is " & myName using "Vicki"
say "Welcome to AppleScript, " & myName using "Alex"

As before, press ‘Command-K’ to compile and ‘Command-R’ to run.

As you can see (or hear!), you can even have your computer continue a dialogue (with or without you!) using OS X’s many voices.

It’s worth noting that this feature is extremely useful if you’re learning a foreign language.

The Voices options in System Preferences > Dictation & Speech | Text to Speech | System Voice include many optional voices that you can download that will speak foreign text. You can paste the target text into a dialog box (like the ones you just created), and then listen and practice your language skills as repetitively as you desire. For those wanting to learn Thai, for example, download the voice “Narisa”. You can paste Thai script from the web or from the Dictionary.app (if you have the Thai extension installed) into a dialog box and have “Narisa” say it in a very passable Thai accent. Great for learning!

One last one. How about your own screencapture program? Tired of remembering those shortcut keybindings, or having to fire up Preview or SnagIt for the occasional screen grab? Why not have your own app in the Dock that captures the screen with a single click? Here’s how:

Open a new editor window and enter this (in this case, you might want to copy and paste it, for reasons I’ll explain shortly):


do shell script "screencapture -x ~/Desktop/" & time string of (current date) & ".png"

Do the Command-K thing, but then this time do Command-S instead of Command-R. From the resulting save box, change the File Format near the bottom of the box from ‘Script’ to ‘Application’. Give it a fancy name (ScreenGrab, say?) and save it in your Applications folder.

applescript save as

Once that’s all done, go to your Apps folder, grab the ScreenGrab.app and drag it to the Dock. Clicking on it puts a timestamped screenshot on your Desktop. If you’ve got multiple spaces open, flip between them clicking the ScreenGrab app. That’s one easy way to get a record of your entire set up! Cool, huh? (Don’t forget you can easily change the icon in the Dock for something more to your taste, as I explain here. Also, if you don’t like the / delimiters in the file name, use this version for your app.)

That last little script demonstrates one of AppleScript’s most powerful features: the ability to run other scripts (and apps). The command in the last script (and the reason why I suggested you paste it) was actually a Bash shell command (aka Terminal command), and we know those are very easy to mistype! AppleScript can actually run the commands of many apps from within its own scripts, putting the power of those apps at your disposal (and that includes some apps you’re very likely familiar with, like Word and Excel).

I hope this short intro has given you a taste for exploring AppleScript and finding out more. It’s an incredibly powerful language that you can use to enormous advantage, and profit. In order to do that, you’ll need to go on a learning adventure, but I promise, the following sources will make that relatively painless!

If you’re absolutely brand new to AppleScript, then the must-have starter’s book is

AppleScript 1-2-3

Once you’ve got through that you’ll be able to pretty much teach yourself the rest, picking it up from sources like

Macscripter.net

Other references you should consult once you’re up and running are

Learn AppleScript (Sanderson)

and don’t forget Apple’s own free guide:

AppleScript Language Guide which you can also download as a PDF for offline use.

Finally, my Mac OS X Technologies User Tip contains some of the above links as well as others that may be of interest.

Happy scripting! 🙂






Featured picture: wall and paper stencil by -endlesshate






creating secure folders and files



With FileVault 2 having a number of drawbacks, a common question I’m seeing is how best to secure data on Lion and Mountain Lion without using FV2.

There’s a number of tricks on offer, from making transparent folders, excluding folders from Spotlight, or using Terminal to make them invisible or hidden.

However, all of these methods suffer from one inevitable drawback: anyone who knows their way around Terminal can open, read, copy or delete your folders as if you had never employed any of the above tricks at all. Well, not many people know their way around Terminal you say? But everyone knows their way around Google, and learning how to find files via the Terminal is information easily found, even on Applehelpwriter! In short, all those methods listed above are really a waste of time if it’s security that you’re after.

Fortunately, there is a simple answer to securing localised files or folders, and that’s to make a local encrypted disk image with Disk Utility and then move your data into it. To do so, follow this procedure:

1. Open Disk Utility (Applications/Utilities/Disk Utility.app)

2. Click near the bottom of the sidebar in empty space to make sure none of the disks in the sidebar are selected.

3. Click the New Image icon in the task bar.

4. Give the image a name and choose a location to store it. Storing it in the User Library is not a bad idea. Give it a boring name like ‘old system’, ‘old data’ or something like that, but don’t hit ‘Create’ just yet.

5. At the bottom of the dialogue box is a field for encryption. Click on the option button and choose either 128-bit or 256-bit (the second choice is the strongest but also slower. 128-bit is still so strong that almost no-one save the CIA will be able to crack it!)

6. Create a password that you’re not going to forget. Do NOT use the same password that you use for your Admin account or for anything else for maximum security. Uncheck the ‘save in my keychain’ option.

Warning!

if you forget the password don't waste time seeking help trying to break it. The system is designed to be uncrackable. If you forget the password, your data is lost for good.

PRO TIP: For that reason, you might like to use a password manager like ‘1Password‘ for this and all your other passwords. The main reason people forget passwords is infrequency of use. With 1Password you use a single password to unlock all your other passwords and to have them entered automatically into web pages and other fields.


7. Set up the rest of the options as in the screenshot below.




8. When you’re ready, press ‘Create’ to make the disk image.

9. Once the image has been created, copy the files you want to protect into the disk image window, just like you would a hard disk or other connected device. Now, whenever you want to access your protected data, just click on the disk image and enter the password and your data is ready to be used.

10. Test mounting and ejecting the disk image a few time. Open a few files and save your changes. After you’re sure everything is working as expected, delete the files from the original location that you copied them from. Also, don’t forget to eject the disk image in Finder’s sidebar each time when you’re done using it to prevent anyone else accessing your protected files.

🙂


how to change all Desktop backgrounds



With Lion came the welcome ability to have individual background wallpapers for each Desktop. However, what Apple forgot to add was an option to easily make all the Desktops have the same background image when you want it that way.

There are a few workarounds, but probably the simplest – once it is setup – is to use this little script I wrote for some ASC members. It should take you about 5 to 10 minutes to set this up if you follow the procedure carefully.

1. Open TextEdit, and choose TextEdit > Preferences.
Change the settings from ‘Rich Text’ to ‘Plain text’ for New Documents. Close the Preference pane and chose File > New.

2. Copy everything in the box below and paste it into the TextEdit file you just opened:

#! /bin/bash
#script to change all desktop backgrounds

echo -n “Drag and drop an image file here then press ‘return’ or
press ‘control-c’ to cancel…”
read -e WLPR;

function change_wallpaper
{
defaults write com.apple.desktop Background “{default = {ImageFilePath=’$WLPR’; };}”; killall Dock
}
change_wallpaper

3. Save the file to

/Library/Desktop Pictures

with the name ‘ChangeAllDesktops’.

IMPORTANT: Make sure you remove the ‘.txt’ file extension in the name field AND uncheck the option at the bottom of the Save box that says ‘If no extension is provided, use .txt’.

Note that you will need to press the ‘authenticate’ button when prompted in order to save anything into the ‘Desktop Pictures’ folder. Type your password in the dialogue that pops up.

4. Open Terminal.app.
Make the ‘ChangesAllDesktops’ file executable by copy/pasting this into the Terminal window:

sudo chmod a+x /Library/Desktop\ Pictures/ChangeAllDesktops

Press ‘return’ and type in your password. The password won’t echo to the screen, so type carefully.

5. Make Terminal the default app for the file
Open a Finder window. Click on your hard disk icon in the sidebar (if you can’t see it, go to Finder > Preferences > Sidebar and check Hard disks under the ‘Devices’ section). Navigate to the Library/Desktop Pictures folder and right-click on the ‘ChangeAllDesktops’ file.

Select Open with and then Other…. In the window, navigate to Terminal.app in /Applications/Utilities. It will be greyed out, so change “Recommended Applications” to “All Applications” in the menu at the bottom of the window. Do not check “Always Open With”. Choose ‘Terminal.app’ and ‘OK’.

6. Make a shortcut for Desktop Pictures
Drag the folder ‘Desktop Pictures’ to the Finder sidebar to make a convenient shortcut. Now when you want to change all Desktop backgrounds at the same time, click in ‘Desktop Pictures’ in the Finder sidebar, run the ‘ChangeAllDesktops’ file, and drag an image from the (already) open Finder window into the Terminal window that appears.

Press ‘return’ and your desktops are all changed! 🙂



Related Posts
learning the Terminal — Part One
learning the Terminal — Part Two

%d bloggers like this: