{"id":332,"date":"2020-01-07T01:45:00","date_gmt":"2020-01-07T06:45:00","guid":{"rendered":"http:\/\/www.brunerd.com\/blog\/?page_id=332"},"modified":"2025-04-22T23:52:38","modified_gmt":"2025-04-23T04:52:38","slug":"software","status":"publish","type":"page","link":"https:\/\/www.brunerd.com\/blog\/software\/","title":{"rendered":"Software"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">Command line Utilities for the Administrator:<\/h3>\n\n\n\n<p><strong>plb<\/strong> &#8211;\u00a0&#8220;plist broker&#8221;\u00a0can\u00a0<strong>visualize<\/strong>\u00a0a plist in a like my tool\u00a0<code><a href=\"https:\/\/github.com\/brunerd\/jpt\">jpt<\/a><\/code>\u00a0does for JSON.\u00a0<code><code><a href=\"https:\/\/github.com\/brunerd\/plb\" target=\"_blank\" rel=\"noreferrer noopener\">plb<\/a><\/code><\/code>\u00a0can map out the complete paths and values that may be buried within nested dictionaries and arrays. It can help you see the \u201cshape\u201d of a plist and recognize patterns. <code><a href=\"https:\/\/github.com\/brunerd\/plx\" target=\"_blank\" rel=\"noreferrer noopener\">plx<\/a><\/code> the\u00a0<strong>plist extractor<\/strong> is a minimal version for extraction only. Both are shell scripts\u00a0<em>and<\/em>\u00a0functions you can incorporate into\u00a0<em>your<\/em>\u00a0own scripts, like my other embeddable tools:\u00a0<code><a href=\"https:\/\/github.com\/brunerd\/jpt\" target=\"_blank\" rel=\"noreferrer noopener\">jpt<\/a><\/code>,\u00a0<code><a href=\"https:\/\/github.com\/brunerd\/ljt\" target=\"_blank\" rel=\"noreferrer noopener\">ljt<\/a><\/code>,\u00a0<code><a href=\"https:\/\/github.com\/brunerd\/jse\" target=\"_blank\" rel=\"noreferrer noopener\">jse<\/a><\/code>\u00a0and\u00a0<code><a href=\"https:\/\/github.com\/brunerd\/shui\" target=\"_blank\" rel=\"noreferrer noopener\">shui<\/a><\/code><br>Github project page: <code><code><a href=\"https:\/\/github.com\/brunerd\/plb\" target=\"_blank\" rel=\"noreferrer noopener\">plb<\/a><\/code><\/code><br>Tagged blog posts: <a href=\"https:\/\/www.brunerd.com\/blog\/tag\/plb\">tag\/plb<\/a><\/p>\n\n\n\n<p><strong>clui<\/strong> &#8211; &#8220;command line Unicode info&#8221; is like the built-in Character Viewer for the macOS Terminal, get info about any Unicode character. Search for them by description or component character. Get the Code Point, descriptions (Unicode and\/or Apple), UTF-8, 16, or 32 encodings. Can output results in several formats: plain text, CSV, JSON, and RTF.<br>Github project page: <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/brunerd\/clui\" target=\"_blank\">clui<\/a><br>Tagged blog posts: <a rel=\"noreferrer noopener\" href=\"https:\/\/www.brunerd.com\/blog\/category\/projects\/clui\/\" target=\"_blank\">projects\/clui<\/a><\/p>\n\n\n\n<p><strong>ljt<\/strong> &#8211; The &#8220;little JSON tool&#8221; is a safe and easy way to parse JSON and retrieve values natively in <em>your<\/em> shell scripts, no external dependencies required! Like the <code>jpt<\/code> it too is a shell script that leverages the Javascript binary <code>jsc<\/code>, however unlike the <code>jpt<\/code>, this little JSON tool only <em>gets<\/em> values, nothing else. This keeps it nice and small and easily embedded into your shell scripts, the minified function is a scant 1.9k<br>Github project page: <a href=\"https:\/\/github.com\/brunerd\/ljt\">ljt<\/a><br>Tagged blog posts: <a href=\"https:\/\/www.brunerd.com\/blog\/category\/scripting\/ljt\/\">scripting\/ljt\/<\/a><\/p>\n\n\n\n<p><strong>jpt<\/strong> &#8211; the &#8220;JSON Power Tool&#8221; is a Javascript and shell polyglot script that leverages <code><a rel=\"noreferrer noopener\" href=\"https:\/\/trac.webkit.org\/wiki\/JSC\" target=\"_blank\">jsc<\/a><\/code>, the <a rel=\"noreferrer noopener\" href=\"https:\/\/trac.webkit.org\/wiki\/JavaScriptCore\" target=\"_blank\">JavascriptCore<\/a> binary that is standard on <em>every<\/em> Mac since 10.4! Since the jpt is purposefully written in ES5 to maintain maximum compatibility, then why <em>yes<\/em>, this tool <em>does<\/em> run on both PPC and Intel Macs all the way back to OS X Tiger and then all the way forward to the latest macOS! Many Linux distros like CentOS and Ubuntu come with jsc pre-installed also, even Windows with the Linux Subsystem installed can run jsc and therefore can (usually) run the <code>jpt<\/code>! <\/p>\n\n\n\n<p>What you can do with the jpt? Query JSON documents using either the simple yet expressive <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/brunerd\/jpt\" target=\"_blank\">JSONPath<\/a> syntax or the singular and precise JSON Pointer (<a rel=\"noreferrer noopener\" href=\"https:\/\/tools.ietf.org\/html\/rfc6901\" target=\"_blank\">RFC6901<\/a>) syntax. The output mode is JSON but additional creative output modes can render JSONPaths, JSON Pointer paths, or even just the property names with their &#8220;constructor&#8221; types (try -KC with -J or -R) Textual output can be encoded in a variety of formats (hex\/octal\/URI encoding, Unicode code points, etc&#8230;), data can be modified using both <a rel=\"noreferrer noopener\" href=\"http:\/\/jsonpatch.com\" target=\"_blank\">JSON Patch<\/a> (<a href=\"https:\/\/tools.ietf.org\/html\/rfc6902\">RFC6902<\/a>) operations (add, replace, remove, copy, move, test) and also  <a rel=\"noreferrer noopener\" href=\"https:\/\/tools.ietf.org\/html\/rfc7396\" target=\"_blank\">JSON Merge Patch<\/a> (<a rel=\"noreferrer noopener\" href=\"https:\/\/tools.ietf.org\/html\/rfc7386\" target=\"_blank\">RFC7386<\/a>) operations. JSON can be worked with in new ways, try <code>-L<\/code> for &#8220;JSONPath Object Literal&#8221; output to see what I mean. Or you simply feed <code>jsc<\/code> a file to pretty-print (stringify) to \/dev\/<code>stdout<\/code>. I&#8217;ll be writing more about this one for sure.<br>Github project page: <a href=\"https:\/\/github.com\/brunerd\/jpt\">jpt<\/a><br>Tagged blog posts: <a rel=\"noreferrer noopener\" href=\"https:\/\/www.brunerd.com\/blog\/category\/scripting\/jpt\/\" target=\"_blank\">scripting\/jpt<\/a><br><\/p>\n\n\n\n<p><strong>shui<\/strong> &#8211; first-class Applescript dialog boxes in your shell scripts without needing to remember esoteric Applescript phrasings! If you think it&#8217;s odd for code to have possessive nouns and are more comfortable in shell, you&#8217;re not alone. shui can be embedded in either bash or zsh scripts but it can <em>also<\/em> output Applescript if you really want to know how the sausage is made or want to embed in your script without shui. Hopefully shui will let you forget those awkward Applescript phrasing and focus on your shell script&#8217;s features and functionality. It uses <code>osascript<\/code> to execute the Applescript and <code>launchctl<\/code> to invoke <code>osascript<\/code> in the correct user context so user keyboard layouts are respected (vs. root runs). Check out the project page for demo videos and then give <strong>shui<\/strong> a try.<br>Project page: <a href=\"https:\/\/github.com\/brunerd\/\" target=\"_blank\" rel=\"noreferrer noopener\">shui<\/a><br>Tagged blog posts: <a href=\"https:\/\/www.brunerd.com\/blog\/category\/scripting\/shui\/\" target=\"_blank\" rel=\"noreferrer noopener\">scripting\/shui<\/a><\/p>\n\n\n\n<p><strong>shef<\/strong> &#8211; Shell Encoder and Formatter &#8211; Transform arbitrary text into 7-bit ASCII using a variety of <strong>shell encoding<\/strong> and <strong>quoting styles<\/strong>. Output can be used in shell scripts or passed into shell script by other tools that don&#8217;t require shell quoting. Useful for systems that don&#8217;t support 4-byte UTF-8 encoded characters.<br>Project page: <a href=\"https:\/\/github.com\/brunerd\/shef\" data-type=\"link\" data-id=\"https:\/\/github.com\/brunerd\/shef\" target=\"_blank\" rel=\"noreferrer noopener\">shef<\/a><br>Tagged blog posts: <a href=\"https:\/\/www.brunerd.com\/blog\/category\/projects\/shef\" data-type=\"link\" data-id=\"https:\/\/www.brunerd.com\/blog\/category\/projects\/shef\" target=\"_blank\" rel=\"noreferrer noopener\">projects\/shef<\/a><\/p>\n\n\n\n<p><a href=\"http:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/ppdOptionsDiff.command.zip\">ppdOptionsDiff.command<\/a>&nbsp;&#8211; Compares the stock PPD (in \/Library\/Printers) with the installed PPD (\/etc\/cups\/ppd) to produce &#8220;-o&#8221; options for use with lpadmin (see article <a title=\"Getting and setting PPD options via command line for use with lpadmin in OS X\" href=\"http:\/\/www.brunerd.com\/blog\/2012\/03\/13\/getting-and-setting-ppd-options-via-command-line-for-use-with-lpadmin-in-os-x\/\">here<\/a>)<\/p>\n\n\n\n<p><a href=\"http:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/setUserTemplateDefaultDocks.sh_.zip\">setUserTemplateDefaultDocks<\/a> &#8211; For the Jamf Pro admin, this will copy the localized default.plist from inside Dock.app to the appropriate localized User Template folder, adding a GUID and file-label to each entry to satisfy the Jamf Pro Dock Item payload code that looks for these elements when adding or removing icons. <em>Failing<\/em> to add these&nbsp;Jamf Pro will <strong>nuke<\/strong> the default.plist FYI<\/p>\n\n\n\n<p><a href=\"http:\/\/brunerd.com\/software\/RemoveItemFromDock\/RemoveItemFromDock.dmg\">RemoveItemFromDock<\/a> &#8211; Command line utility to remove items from the dock<\/p>\n\n\n\n<p><a href=\"http:\/\/brunerd.com\/software\/AddItemToDock.dmg\">AddItemToDock<\/a> &#8211;&nbsp;Command line utility to add items to the dock.<\/p>\n\n\n\n<p><a href=\"http:\/\/brunerd.com\/software\/AddLoginItem.dmg\">AddLoginItem<\/a> &#8211; Command line utility to add items to users&#8217; login items<\/p>\n\n\n\n<p><a href=\"http:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/createRecoveryHDUpdater-15.4.6.command.zip\">createRecoveryHDUpdater 15.4.6.command<\/a>&nbsp;&#8211; built&nbsp;PKG now is targetable to volumes other than \/ (Note:&nbsp;Recovery HD&nbsp;updater packages for 10.11&nbsp;will&nbsp;<strong>only<\/strong>&nbsp;work when run in OS X 10.11, previous packages could run in different OSes not so for 10.11). This is only useful for HFS+ formatted disks. APFS need not apply (it will make an HFS+ partition on your APFS disk BTW)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Widgets for Wonks:<\/h3>\n\n\n\n<p>Rebuilt with <a rel=\"noreferrer noopener\" aria-label=\"Platypus (opens in a new tab)\" href=\"https:\/\/sveinbjorn.org\/platypus\" target=\"_blank\">Platypus<\/a> (5.3) these 64-bit menubar apps will still run on Catalina, however they are un-notarized and unsigned. But why trust me or Apple, if you want to know what the do just look inside at the bash script that makes it tick.<\/p>\n\n\n\n<p><a href=\"http:\/\/brunerd.com\/software\/XProtectPluginChecker.zip\">XProtectPluginChecker<\/a>&nbsp;&#8211; Quickly survey the status of Java, Flash, and any other Plug-Ins Apple deems insecure and unworthy of your usage.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/XProtectPluginChecker-Menu-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"295\" height=\"294\" src=\"http:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/XProtectPluginChecker-Menu-2.png\" alt=\"XProtectPluginChecker Menu 2\" class=\"wp-image-548\" srcset=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/XProtectPluginChecker-Menu-2.png 295w, https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/XProtectPluginChecker-Menu-2-150x150.png 150w\" sizes=\"auto, (max-width: 295px) 100vw, 295px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><a href=\"http:\/\/brunerd.com\/software\/myXProtectStatus.zip\">myXProtectStatus<\/a> &#8211; A drop down status menulet, showing date, version,&nbsp;and threats protected against in the Xprotect plist. Written in bash, wrapped by Platypus, it is informational only (so don&#8217;t ask me to add some menu item to <em>do<\/em> something, it just reports). Tuck it away somewhere and add to your loginitems.<\/p>\n\n\n\n<p>Screenshot of myXProtectStatus:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><figure><img loading=\"lazy\" decoding=\"async\" title=\"myXProtect\" width=\"349\" height=\"471\" class=\"alignnone size-full wp-image-376\" src=\"http:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/myXProtect.png\" alt=\"\" srcset=\"https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/myXProtect.png 349w, https:\/\/www.brunerd.com\/blog\/wp-content\/uploads\/myXProtect-222x300.png 222w\" sizes=\"auto, (max-width: 349px) 100vw, 349px\" \/><\/figure><\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">Exercises in&nbsp;Applescript :<\/h3>\n\n\n\n<p>If you have OS X 10.5 you&#8217;ll think this is neat&#8230; you&#8217;ll also be on a very old computer&#8230;<\/p>\n\n\n\n<p><a href=\"http:\/\/brunerd.com\/software\/ToggleDock\/ToggleDock.dmg\">ToggleDock<\/a>&nbsp;&#8211; Toggle the Dock appearance from &#8220;glass&#8221; to &#8220;no glass&#8221; when in horizontal mode.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Command line Utilities for the Administrator: plb &#8211;\u00a0&#8220;plist broker&#8221;\u00a0can\u00a0visualize\u00a0a plist in a like my tool\u00a0jpt\u00a0does for JSON.\u00a0plb\u00a0can map out the complete paths and values that may be buried within nested dictionaries and arrays. It can help you see the \u201cshape\u201d of a plist and recognize patterns. plx the\u00a0plist extractor is a minimal version for extraction [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-332","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/pages\/332","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/comments?post=332"}],"version-history":[{"count":40,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/pages\/332\/revisions"}],"predecessor-version":[{"id":1690,"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/pages\/332\/revisions\/1690"}],"wp:attachment":[{"href":"https:\/\/www.brunerd.com\/blog\/wp-json\/wp\/v2\/media?parent=332"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}