Applescript variable question


I have an Applescript that I execute in KM, is it possible to set strPrinterName to the last used printer? if so, which wording will I need to use?

set strPrinterName to “HP Officejet Pro X551dw Printer”

tell application strPrinterName
print strPosixPath
end tell

Thank you

To get the default and most recent printers in JavaScript for Automation, I might write something like this:

(function() {
	'use strict';


	var a = Application.currentApplication(),
	sa = (a.includeStandardAdditions = true, a);

	return {
		default: $,
		latest: sa.doShellScript('lpstat -W completed | head -n 1')

In AppleScript (others will have a clearer idea) I think you may be able to write something like this for the latter:

set {dlm, my text item delimiters} to {my text item delimiters, " "}
set strPrinter to text item 1 of (do shell script "lpstat -W completed | head -n 1")
set my text item delimiters to dlm

1 Like

Thanks for this it works, but how do i get the name of the printer as it is shown on the Mac?

Much appreciated.

Different repositories of name strings – I’m not aware of a simple way of mapping them.

The best you can do may be to replace the underscores with spaces and drop the final number.

Hey Ali,

Give this a try from an Execute a Shell Script action.

It grabs the last used printer with lpstat and then tries to match it in the printers directory.

cd ~/Library/Printers/;
lastUsedPrinter=$(lpstat -W completed \
| head -n 1 \
| sed -E '
   s!_[0-9]+-[0-9]+ .+!!
echo $lastUsedPrinter;

It works on my system, but the only printer I have installed is a Brother HL-2170W series.


1 Like

On the system here that's giving:

AdobePDF8-133 houthakker 18432 Tue Jun 7 10:28:42 2016*

Not sure if that is what @demirtas1 is after.

One other approach, which yields

Adobe PDF 8.0

Might be something like this:

MRU printer.kmmacros (19.7 KB)

JavaScript source:

(function () {
    'use strict';

    // directoryContents :: FilePath -> [FileName]
    function directoryContents(strPath) {
        return ObjC.deepUnwrap(
                .stringByStandardizingPath, null

    // commonPrefix :: String -> String -> String
    function commonPrefix(s, s1) {

        // cpfx :: [Char] -> [Char] -> [Char]
        function cpfx(xs, ys) {
            return (xs.length && ys.length) ? (
                xs[0] === ys[0] ? (
                        cpfx(xs.slice(1), ys.slice(1))
                ) : []
            ) : [];

        return cpfx(s.split(''), s1.split(''))

    var a = Application.currentApplication(),
        strLatest = (a.includeStandardAdditions = true, a)
        .doShellScript('lpstat -W completed | head -n 1')
        .split(' ')[0]
        .replace(/_/g, ' '),

        lstPrinters = directoryContents('~/Library/Printers')
        .map(function (x) {
            return x.slice(0, -4); // '.app' dropped

    return lstPrinters[
        .reduce(function (a, x, i) {
            var lngMatch = commonPrefix(strLatest, x.replace(/\s+/g, ''))

            return (lngMatch > a.length ? { // longer than previous matches ?
                index: i,
                length: lngMatch
            } : a);
        }, {
            index: 0,
            length: 0
    ]; // harvesting just the index from the .reduce() accumulator

Hey @ComplexPoint

That works nicely here for my Brother printer.

See if this works for you on your system.

cd ~/Library/Printers/;
lastUsedPrinter=$(lpstat -W completed \
| head -n 1 \
| sed -E '
   s! *'"$USER"'.+!!
   s!_! !g
   s!([a-z])([A-Z]{2,})!\1 \2!g
   s!([A-Z]{2,}([a-z]))!\1 \2!g
   s! !*!g
echo $lastUsedPrinter;


[ Edited 2016/06/08 04:09 CST – minor fix. ]

Well, here that is returning:


Where the JSA script above returns:

Adobe PDF 8.0

PS we might have to ask the original poster to unpack a little more of the requirements expressed in:

how do i get the name of the printer as it is shown on the Mac

but it doesn't look to me as if there is necessarily a regex-definable relationship between the lpstat naming conventions and those used for the app files in ~/Library/Printers

perhaps deriving an index into a list of the latter from a search for longest shared prefix is about all that can be done ?

Hm... That's weird. I'm basing the new script on my own printer and the string you provided earlier:

AdobePDF8-133 houthakker 18432 Tue Jun 7 10:28:42 2016*

When I plug your lpstat string into my script here it works (of course I have to change the user-name).

Evidently there's something different at your end.

What's the bare result of lpstat -W completed | head -n 1 on your system?


Whitespace composition ? Or the forum display subtly obscuring part of your regex from view or copy/paste ?

The raw lpstat output here is:

AdobePDF8-133           houthakker        18432   Tue  7 Jun 10:28:42 2016

(The string I posted above, with trailing *, was of course, the output rather than the input – perhaps also a source of mismatch ?)

Yep. Try the edited version in post #7.

I had to allow for more whitespace before the user name.


Good ! Now yields:

Adobe PDF

Perhaps worth dropping the .app affix ?

Since it's pulling the driver app name directly from the ~/Library/Printers/ folder I'm leaving it be for now.

On the other hand it's a trifling exercise to remove the .app string from the whole.

One can use a Keyboard Maestro Search and Replace Variable action or replace that last line of the shell script with:

# To remove “.app” from the end of the printer name.


echo $lastUsedPrinter;


sed 's!\.app$!!' <<< $(echo $lastUsedPrinter);