Classic Mac OS had no command line, so Apple had to provide a complete graphical interface to everything that a user might ever need to do. As OS X has matured, more and more ‘advanced’ features have been marooned in shell commands. These take ‘dangerous’ controls away from the vast majority of users, but also make self-help and assisted help very much harder.
One solution is to wrap the shell command in a more comfortable interface, usually in the form of a dialog. There’s quite a lot of commercial software which does little more than that. In this case, I wanted to produce an accessible front end to allow the ordinary user to access historical log records – something which Sierra does not (yet) do in Console 1.0. The shell command in question is log
, which is far more capable than Console 1.0, but whose use is not simple.
The basic format of the log show
command in Terminal is:
log show --predicate [] --style syslog --start [] --end [] --info --last []
and is explained in full here.
Typically, the sort of command that we’ll need to build looks like
log show --predicate 'subsystem == "com.apple.TimeMachine"' --style syslog --info --last 3h | cut -c 1-22,43-999 > '~/Documents/outputfile.text'
AppleScript should have been ideal for doing this, if only Apple had not dithered about with it, and left it with only the most rudimentary support for GUI devices like dialogs. It was actually much easier to produce high-quality dialogs for AppleScript twenty years ago, than it is now, although that was due to third-party tools rather than Apple’s.
But, thanks to Shane Stanley (the wizard of AppleScriptObjC), Mark Alldritt (of Late Night Software, for Script Debugger), and a few others, including Apple’s remaining small team of AppleScript engineers, there are tools which make such rapid, lightweight development possible.
My plan for this small project was simple:
- build a dialog with the required controls to give access to the useful options in
log show
- extract from the dialog the options set, and build the appropriate command
- run the command in the shell, sending the output to a text file.
If I had time and inclination, I should have made this a proper AppleScriptObjC project and built a proper native dialog. But that imposes overhead, and at this stage I could not justify it. So the next best option was to use Shane Stanley’s excellent Dialog Toolkit v2.0.2 from here, as a shortcut. This enables me to just code the script up in Script Debugger.
So at the start of the script, we need to require the version of AppleScript provided in Sierra, and to use the Dialog Toolkit and scripting additions.
Shane provides three excellent examples with the toolkit, which show very nicely how to use it. I stole heavily from those, getting my dialog working much as I wanted before worrying about extracting the options set and trying to build the command. So for this dialog:
the code works out as
The series of set {} to …
commands creates each of the items within the dialog, starting at the bottom, and working up to the top. The final set allControls
then builds the list from which we’ll extract the user’s settings. The dialog is then displayed with
If the user clicks on the OK button, then we’ll build the text for the shell command.
I haven’t tried to build in a control for specifying the text file to save output to, as I prefer to follow the standard, and use the familiar chooser:
For simplicity, this goes right at the start of the code, and we’ll wrap the whole thing in a try
, so that if the user cancels or the shell command freaks out, it will be handled properly.
So, if the user does click on OK to dismiss the dialog, this is one way to parse their settings in terms of the options available to log show
. Recall that in text already within “”, \"
encodes the character "
, which we need to embed in the command. For simplicity, the text snippet for each option ends with a single space, to make concatenation consistent. The final concatenation adds the output file, from the initial file chooser dialog.
This is remarkably easy to debug in Script Debugger, which helpfully tells us the value of theAppCmd
each time we run the script. So I exercised each of the dialog settings with the file chooser code commented out (to save time) and thePath
set to a dummy value. Once happy, I restored the file chooser code, and added the final code to run the shell command:
Fewer testing runs then confirmed that this all appeared to work properly.
I saved this as an executable app. The last task is to ensure that app’s package includes Shane Stanley’s Dialog Toolkit, so the user doesn’t have to worry about installing it separately. This requires you to create a folder named Script Libraries inside the app’s Resources folder, and copy Dialog Toolkit.scptd into it. I also put his readme file inside the Resources folder for the sake of completeness.
Here’s the end result for you to play with and re-use as you wish: loglogger2
Resources