Launching Scripts #1: From Terminal

Scripts, no matter which language they are written in, are an incredibly important part of a MacAdmin’s tool kit.

Most posts, books and tutorials focus on how to write scripts. Admittedly, the skill to make the computer and all its software running do what you want is very important. But once you have a working script, you will have to consider how to launch the script at the right time and with the right input.

When I started to think about this, I realized macOS provides many ways to launch or schedule scripts. Some are fairly obvious, others are quite obscure and maybe even frivolous.

Over the next few weeks (i.e. when I find time), I will publish a series of posts describing various ways of launching scripts and workflows on macOS. This post starts with the most obvious: launch a script from Terminal.

The Basics: Launch from Terminal

It might seem trivially obvious that you can launch scripts and workflows from Terminal. Nevertheless, it does require some explanation and context. Launching from Terminal is the most basic form of launching a script. As such, it defines the ‘baseline’ experience of how we expect scripts to run.

Command lookup

When you enter something into a Terminal prompt and hit the return key, the shell will split the text on whitespace. The first element of the text is the command. If that text contains a / character, the shell will interpret the entire element as a path to the executable. The path can be relative or absolute.

If the first element does not contain a / then the shell will first look for functions, aliases and built-in commands, in that order. Then the shell will search for a command executable using the colon-separated paths in the PATH environment variable. It will use the first executable it finds.

If the shell fails to find something to execute, it will show an error.

This is why you need to the ./ to execute scripts in the current working directory. Even though the ./ seems redundant, it tells the shell to look for the executable in the current working directory, instead of using the PATH.

You can find this process described in more detail here. I also have a post on how to configure your PATH variable.

Shebang

Scripts are ‘just’ text files. Two things distinguish them from normal text files.

First, the executable bit is set to tell the system this file contains executable code. You do this with the chmod +x my_script.sh command. Here comes the trick, though. The text in the script file isn’t really executable code that the CPU can understand directly. It needs an ‘interpreter’ which is another program that, wells, interprets the text file and can tell the CPU what to do.

The interpreter for a script file is set in the first line of the script with the #! character combination. The #! is also called ‘hashbang’ or ‘shebang.’ The shebang is followed by an absolute path to the interpreter, e.g. /bin/sh, /bin/bash, or /usr/local/bin/python.

Note: the shebang has to be in the very first line (actually the first characters) of the script, you cannot have comments (or anything else) before it.

Note: you often see shebangs using the env command in the form #!/usr/bin/env bash. These are useful for cross-platform portability, but have trade-offs. I have an article just for that.

Arguments

The shell is only interested in the first part of the command line text you entered. The entire list of parts (or elements, split on whitespace) are passed into the command as its arguments. A shell script sees the first element, the command or path to the command as $0 and the the remaining arguments as $1, $2, and so on.

Other languages will handle this in a similar fashion, arrays or lists of arguments are common.

Environment

Shells also have environment variables. We already talked about the role of the PATH variable in the command lookup. In Terminal, you can list all variables in your current environment with the env command. Some of these environment variables can be extremely useful, like SHELL, USER, and HOME.

When you launch a script from Terminal, a new shell environment is created and all of the environment variables are copied. This is great, beacuse the script can access the environment variables, and might even change them. But the changes in the script’s sub-shell, will not affect the current shell. In other words, a script can change the PATH environment variable in its own context, without changing yours.

In other Unix-based systems, environment variables are a common means of providing data to apps and processes. In the interactive shell on macOS, environment variables are very useful for this purpose. We will see, however, that when you launch processes and scripts through other means, environment variables can be a challenge on macOS.

Note: A shell environment also contains shell options, which are also inherited to sub shells.

Input and Output

Shell scripts and tools also have input and output. When you launch a script from the the Terminal, both output streams (Standard Output and Standard Error) are connected to the Terminal, so the output will be shown in the Terminal window.

When you use a script with pipes, then its Standard Input (stdin) will be connected to the previous tool’s Standard Out (stdout). The last script’s stdout and stderr will be shown in Terminal.

One thing that is special about interactive Terminal input and output, is that it happens while the script or tool is running. That means you can get live updates on the progress.

When we launch scripts in other contexts, their input and output may be buffered. This means that the system waits for the script or tool process to complete before piping its output to the next tool or to the process that called it. This is not something you usually have to worry about, but again it is something you should have in mind when running scripts in non-Terminal contexts.

Conclusion

While glaringly obvious, launching a script from Terminal does have some intricacies. This post sets a ‘baseline’ for how scripts work on macOS. In future installments, we will re-visit some of these topics, and the differences will become relevant when we launch scripts in contexts other than an interactive shell.

In the next post, learn how to create a double-clickable file to launch a script from Finder.

Weekly News Summary for Admins — 2022-04-08

Apple announced dates for WWDC ’22: June 6–10. The conference will be online again, but there will be a live audience “to watch the keynote and State of the Union videos” at Apple Park. This implies that these sessions will also be pre-recorded. Is the era of Apple live events over?


(Sponsor: vast limits)

uberAgent: application performance monitoring

uberAgent Logo

uberAgent is an innovative user experience monitoring product for macOS and Windows. uberAgent’s highlights include detailed information about application performance, network reliability drill-downs, application usage metering, browser performance, and web app metrics. Try for yourself and get your free 100 user community license at uberagent.com.


After last week’s surprise update, Apple released the first round of betas for macOS 12.4 and iOS 15.5 and siblings. We also got new versions of the apps formerly known as iWork: Keynote, Pages, and Numbers.

If you would rather get the weekly newsletter by email, you can subscribe to the Scripting OS X Weekly Newsletter here!! (Same content, delivered to your Inbox once a week.)

📰News and Opinion

🐦MacAdmins on Twitter

  • Léo Natan: “Do you prefer the old style macOS alerts? There is a way to get them globally for AppKit in Big Sur and Monterey: defaults write -g NSAlertMetricsGatheringEnabled -bool false” (via Michael Tsai)
  • Nathaniel Strauss: “TIL HomePod can install wireless profiles”
  • mikey: “If you’ve updated to macOS 12.3.1 your /etc/pam.d/sudo will have been reset, here’s a programatic way to (re-) enable using TouchID to authenticate sudo

🔐Security and Privacy

🔨Support and HowTos

🤖Scripting and Automation

🍏Apple Support

♻️Updates and Releases

🎧To Listen

🎈Just for Fun

📚Support

If you are enjoying what you are reading here, please spread the word and recommend it to another Mac Admin!

If you want to support me and this website even further, then consider buying one (or all) of my books. It’s like a subscription fee, but you also get a useful book or two extra!

Use shellcheck with BBEdit

When I teach or mentor shell scripting on macOS, I always have two recommendations: use BBEdit as your text editor and use shellcheck to verify sh and bash scripts.

I only discovered recently, that the two combine wonderfully!

It used to be that installing the shellcheck command line tool on macOS was a complicated process. Thankfully, the GitHub project now provides a pre-compiled binary for macOS, so you don’t have to mess with all of that anymore. The project labels the macOS version as ‘darwin.’ The binary is x86_64 (Intel) only and requires Rosetta on Apple silicon, but this doesn’t reduce its usefulness.

Installing shellcheck

The easiest way to install the command is to download the archive from the repo, expand the archive, and copy the shellcheck binary to /usr/local/bin/. You can follow the instructions from this earlier post to do it in Terminal or do it with your browser and in the Finder. When you download and unarchive manually, you will have to remove the quarantine flag from the shellcheck command, before you can use it.

> xattr -d com.apple.quarantine shellcheck-latest/shellcheck

I also created shellcheck recipes for AutoPkg, that automate creating a package installer for mass deployment.

Using shellcheck

Once you have the shellcheck command in place, you can use it from the command line:

> shellcheck my_great_script.sh

Sadly, shellcheck will only work with sh and bash scripts, not with zsh scripts. On the other hand, many of the common mistakes that shellcheck catches, (mostly quoting variables) are not mistakes in zsh. Still, I miss it a lot when working on large zsh scripts.

shellcheck with BBEdit

Once you have the shellcheck command installed, you can also invoke from within BBEdit: When you have a script open in BBEdit, verify that the script is recognized as a ‘Unix shell script.’ Then you can select ‘Check Syntax…’ from the ‘#!’ menu (keyboard shortcut ⌘-K). This will open a second window with all the issues shellcheck has found.

This feature was added in BBEdit 13.1, but it took me quite a while to discover it. Now I find it indispensable.

Enjoy!

Weekly News Summary for Admins — 2022-04-01

Yesterday morning, I glanced at the list of links so far and thought it’d be a quiet week… And then surprise update week happened!


(Sponsor: Mosyle)

Mosyle Fuse logo

The Fusion of Apple MDM, Identity, Patching & Security.

Mosyle Fuse is the first and only product to bring a perfect blend of an Enterprise-grade MDM, an innovative solution for macOS Identity Management, automated application installation and patching, and purpose-built multi-layer endpoint security, all specially designed for Apple devices used at work at a price point that’s almost unexplainable.

Click here to learn more!


Aside from suprise updates, we also got the SixColors Apple in the Enterprise Report Card. Many thanks to Jason Snell for putting this together and to everyone who contributed!

If you would rather get the weekly newsletter by email, you can subscribe to the Scripting OS X Weekly Newsletter here!! (Same content, delivered to your Inbox once a week.)

macOS Monterey 12.3.1 and iOS 15.4.1

macOS Monterey 12.3.1

iOS 15.4 and iPadOS 15.4

watchOS 8.5.1, tvOS and HomePod

Apps and Services

Reactions

News and Opinion

Security and Privacy

Support and HowTos

Scripting and Automation

Apple Support

Updates and Releases

To Listen

Just for Fun

Support

If you are enjoying what you are reading here, please spread the word and recommend it to another Mac Admin!

If you want to support me and this website even further, then consider buying one (or all) of my books. It’s like a subscription fee, but you also get a useful book or two extra!

Weekly News Summary for Admins — 2022-03-25

After all the announcements of the last weeks, this week feels quieter. Something must be going in on Cupertino, as we have not gotten betas for macOS 12.4/iOS 15.4 yet. Maybe the developers have to start preparing their WWDC sessions.


(Sponsor: Mosyle)

The Fusion of Apple MDM, Identity, Patching & Security.

Mosyle Fuse logo

Mosyle Fuse is the first and only product to bring a perfect blend of an Enterprise-grade MDM, an innovative solution for macOS Identity Management, automated application installation and patching, and purpose-built multi-layer endpoint security, all specially designed for Apple devices used at work at a price point that’s almost unexplainable.

Click here to learn more!


If you would rather get the weekly newsletter by email, you can subscribe to the Scripting OS X Weekly Newsletter here!! (Same content, delivered to your Inbox once a week.)

News and Opinion

Books

macOS and iOS Updates

MacAdmins on Twitter

  • Mr. Macintosh: “The Mac Studio has arrived! I’ll go over a few details others might not have covered” (Thread)

Security and Privacy

🔨Support and HowTos

Scripting and Automation

Apple Support

Updates and Releases

To Watch

To Listen

Support

If you are enjoying what you are reading here, please spread the word and recommend it to another Mac Admin!

If you want to support me and this website even further, then consider buying one (or all) of my books. It’s like a subscription fee, but you also get a useful book or two extra!

Some CLI updates in macOS Monterey

The other day on Twitter, I got a question about a flag for the readlink command that I was not familiar with. As it turns out, the readlink command (which tells you where a symbolic link points to) got an update in macOS 12.3 and now has a -f option. With this new option, readlink will resolve symbolic links anywhere in the path and print the ‘actual’ absolute path to the item. This is equivalent to the realpath command available on Linux and some programming languages.

I have written about this before, and then I mentioned that there is a python function to resolve the path. However, even back then I anticipated the removal of python and suggested using a zsh parameter expansion modifier instead:

resolved_path=${path_var:A}

The removal of Python 2 is the likely explanation for why Apple chose to update readlink in 12.3.

It will be nice to have the new readlink -f option available going forward, but if your script still needs to support versions of macOS older than 12.3 then you should prefer to use the zsh expansion modifier.

More Monterey Command Line Changes?

This was discovered mostly by chance. While Apple’s release notes are improving, there are still nowhere near detailed enough and missing this level of detail, even though that would be amazingly useful.

I remembered that the Kaleidoscope app team had posted a script that allows me to compare man pages between versions of macOS. They published this back when macOS 12 was released to track the changes of the plutil command line tool. With the help of this tool I determined a few more interested changes in macOS 12, the most interesting of which I will summarize here.

(Even with this script, the process was tedious. Many changes to the man pages are just reformatting whitespace and/or typos. I may have missed something. Please, let me know when you find more changes!)

cut

  • new -w option (splits fields on whitespace)

du

  • new -A option (apparent size)
  • new --si option (human-readable, in 1000 based units)
  • new -t option (only show items over a certain threshold)

aa (Apple Archive)

  • new options for encryption
  • new aea command for encrypted Apple Archives

tar

  • new encryption and compression types

find

  • new -quit primary
  • new -sparse primary (so you can find APFS sparse files)

grep

  • new rgrep, bzgrep, bzegrep, and bzfgrep
  • new --label option
  • new -M, --lzma option

hdituil

  • segment subcommand and Segmented images are deprecated
  • UDBZ dmg format (bzip2 compression) is deprecated
  • udifrez and udifderez are deprecated (this allows to embed a license in a dmg)

head

  • new -n and -c options (probably just the man page updated)

killall

  • new -I option (confirm)
  • new -v option (verbose)

ls

open

  • new -u option to open file paths as URLs

pkgbuild

  • new --large-payload option
  • new --compression option
  • new --min-os-version option

I have an article on the new pkgbuild options.

plutil

  • new -type option for extract
  • new -raw option for extract
  • new type subcommand to query type
  • new create subcommand to create a new empty plist

pwd

  • new -p option prints working directory with symbolic links resolved

readlink (12.3)

  • new -f option to resolve symbolic links

rm (12.3)

  • new -I option which prompts only when more than three files will be deleted or a directory is being removed recursively

shortcuts

  • new command to run, list, or interact with Shortcuts

smbutil

  • new multichannel and snapshot verbs

Also, the nano command now actually opens pico. (Thanks, @rgov) Most people won’t notice this, as the two are quite similar. The excision of GNU tools from macOS continues.

Weekly News Summary for Admins — 2022-03-18

Update week! We got macOS 12.3, iOS 15.4 and all the siblings this week. Did you already update? Your users?


(Sponsor: Mosyle)

The Fusion of Apple MDM, Identity, Patching & Security.

Mosyle Fuse logo

Mosyle Fuse is the first and only product to bring a perfect blend of an Enterprise-grade MDM, an innovative solution for macOS Identity Management, automated application installation and patching, and purpose-built multi-layer endpoint security, all specially designed for Apple devices used at work at a price point that’s almost unexplainable.

Click here to learn more!


My most anticipated and now favorite feature in these updates is Universal Control. You can tell it still has a few rough edges (despite the delay, Apple still labels it as ‘beta’) but it is already eminently useful. The (already high) usefulness of my iPad Air 4 increased dramatically. Universal Control lets the iPad do what does best, while still being just a trackpad swipe away from the Mac.

But Apple gives and takes away. Long forwarned, this update really removed the Python 2 binary, and yes, some admins, and developers were still blindsided. I have built a summary of links to posts, issues and solutions on my weblog and will keep updating that post over the next few weeks.

Apple developers must be taking a well-deserved break, beacuse we have not seen the macOS 12.4 beta yet. Any day now. Remember to remove the developer/beta profile!

If you would rather get the weekly newsletter by email, you can subscribe to the Scripting OS X Weekly Newsletter here!! (Same content, delivered to your Inbox once a week.)

macOS 12.3 Monterey and iOS 15.4

macOS Monterey 12.3

iOS 15.4 and iPadOS 15.4

watchOS 8.5

tvOS and HomePod

Apps

Reactions

Support

Security and Privacy

Support and HowTos

Scripting and Automation

Updates and Releases

To Listen

Support

If you are enjoying what you are reading here, please spread the word and recommend it to another Mac Admin!

If you want to support me and this website even further, then consider buying one (or all) of my books. It’s like a subscription fee, but you also get a useful book or two extra!

Update: Installomator 9.1

We have updated Installomator. This brings Installomator to 407(!) applications! Many thanks to everyone who contributed.

Note: Both Google and Mozilla recommend using the pkg installers instead of the dmg downloads for managed deployments. So far, Installomator has provided labels for both. (googlechrome and googlechromepkg or firefox and firefoxpkg, respectively) Since there are problems with the dmg downloads, a future release of Installomator will disable the firefox and googlechrome dmg labels. You should switch to using the respective pkg labels instead.

  • added option for Microsoft Endpoint Manager (Intune) to LOGO
  • minor fixes
  • the googlechrome label now always downloads the universal version
  • 16 new labels
  • 6 updated labels

Full release notes in the repo.

macOS Monterey 12.3 removes Python 2 – Link collection

Note: I will update this post for the next few weeks with new and updated information. If you find anything that is interesting, ping me on MacAdmins Slack or Twitter as @scriptingosx.

Last Updated: 2022-03-23

What is going on!?

Tools

Updates

  • dockutil: command line tool for managing dock items
  • quickpkg: wrapper for pkgbuild to quickly build simple packages from an installed app, a dmg or zip archive
  • Mist: A Mac command-line tool that automatically downloads macOS Installers/Firmwares
  • DownloadFullInstaller: macOS application written in SwiftUI that downloads installer pkgs for the Install macOS Big Sur application
  • SUS Inspector 2.1: Inspect Apple software update service
  • mkuser: Make user accounts for macOS with many advanced options

Replacing Python

Support

Weekly News Summary for Admins — 2022-03-11

Apple’s “Peek Performance” event this week, delivered plenty of great news. A new iPhone SE, which is mostly identical to the 2020 model, but now uses the A15 chip. Green color choices for the iPhones 13 and 13 Pro. A new iPad Air, using the M1 chip. And then… a new desktop Mac model called “Mac Studio” using the M1 Max or a doubled up M1 Mac chip which Apple calls the “M1 Ultra.” And a new 27″ 5K Studio Display to go along with the Mac Studio.


(Sponsor: Mosyle)

The Fusion of Apple MDM, Identity, Patching & Security.

Mosyle Fuse logo

Mosyle Fuse is the first and only product to bring a perfect blend of an Enterprise-grade MDM, an innovative solution for macOS Identity Management, automated application installation and patching, and purpose-built multi-layer endpoint security, all specially designed for Apple devices used at work at a price point that’s almost unexplainable.

Click here to learn more!


These are great products that will certainly fill many checkboxes in many people’s and organization’s wish lists. Untypically for Apple, there were a few hints on what is yet to come. At the end of the video, John Ternus (SVP of Hardware Engineering) mentions, there is “just one more product to go: the Mac Pro, but that is for another day.” Earlier in the event, John says the M1 Ultra will be the last chip added to the M1 family.

This sets up the intriguing question on how an Apple silicon based Mac Pro will exceed the performance set by the Mac Studio. Some speculate the Mac Pro will be the first Mac to get the next generation Apple silicon chip. However, announcing the M2 with the Mac Pro, would stifle demand on all the other Mac models though, as people will hold off purchases until those product lines are updated, as well. Apple runs a risk of “Osborning” their most popular Mac product lines. It is more likely the M2 will be introduced with the MacBook Air, MacBook Pro, or a successor model to one of these.

We also learned which Mac model will not transition: The 27″ iMac disappeared from the Apple Store this week. Apple seems to consider the Mac Studio with Studio Display a valid replacement. This combo may seem much more expensive than the base iMac 27″, but the Studio Display will likely outlive the Mac it is purchased with, making the direct comparison difficult.

Interestingly, the Intel Mac mini is still available. Keep in mind that if you need an Intel Mac for Bootcamp or compatibility testing on the Intel platform and older versions of macOS, you should either make plans to retain Intel Macs past the usual lifetime in your organization or puchase a Mac mini or Mac Pro now.

The persistence of the Intel Mac mini calls attention to a strange omission in Apple’s Macs with Apple silicon product line: there is no Mac desktop using the M1 Pro. You can get the iMac 24″ and Mac mini with M1. Mac Studio comes with M1 Max and M1 Ultra. The Intel Mac mini sort of fills the spot where a Mac mini or Mac Studio with the M1 Pro would be. (Both price and feature wise.) It might be that Apple needs all the M1 Pro chips they produce to satisfy demand of the MacBook Pro and we will have to wait for more availability until we see desktop Macs with that chip. This gap is even more annoying beacuse it matches the needs of MacAdmins very well.

Either way, exciting times for the Mac, with more interesting things to come!

Oh, the new Mac Studio will require macOS 12.3 and ship next week, so we will also get the macOS 12.3 update next week, which should not come as a huge suprise as Apple released 12.3 RC to AppleSeed this week.

If you would rather get the weekly newsletter by email, you can subscribe to the Scripting OS X Weekly Newsletter here!! (Same content, delivered to your Inbox once a week.)

News and Opinion

Security and Privacy

Support and HowTos

Scripting and Automation

To Watch

To Listen

Just for Fun

Support

If you are enjoying what you are reading here, please spread the word and recommend it to another Mac Admin!

If you want to support me and this website even further, then consider buying one (or all) of my books. It’s like a subscription fee, but you also get a useful book or two extra!