One of the most fundamental features of macOS, and a defining difference between it and iOS, is the ability of users and system administrators to run commands and shell scripts. Not that many users do so consciously, but without that ability, managing macOS becomes far more difficult, and in parts impossible.
This is because of all the added complexities in macOS, to cater for its many and varied uses and users. The myriad of controls and features cannot all be exposed in GUI tools, and Apple has made a conscious effort to limit those which are offered to the ‘ordinary user’ to protect people from their own curiosity and tinkering. Administering a network of Macs also requires access to a lot of features within it which are only accessible through Terminal and shell scripts.
Commands and shell scripts have to rely on some fairly fundamental assumptions about the underlying operating system. One of the most basic is the constancy of file names, and the consistency of directories and their paths within the file system. The human interface can play all sorts of clever tricks in presenting those to the user, but if there’s a file named this.text in the path /here/there/everywhere/, then commands need to be able to rely on that to access that file.
Whatever your feelings about the consistency or otherwise of the human interface to iCloud, Apple’s current engineering solution breaks consistency of file names and paths. When a file has been evicted from local storage, and only exists in full in iCloud storage, the local stub file uses the previous name prefixed with a stop/period, and gains the extension of .icloud. When that file is downloaded to local storage – something which can be triggered by all sorts of events – the leading stop/period and the extension are stripped.
The only way to ensure consistency in local file names and paths when running a command or script is to disconnect that Mac from its iCloud storage until that command or script has completed.
It is, of course, quite feasible to write scripts which will cope with these filename changes, and they have a certainly utility in indicating whether a given file has been evicted from local storage. But having to test many files for name mutation is clumsy and prone to error.
When a Mac is only connected to iCloud Drive, this may not be of much significance. Many commands and scripts can safely ignore files which the user has placed in their iCloud Drive. But the moment that a user enables Desktop & Document Folders to be stored in iCloud, with Optimize Mac Storage enabled, file names in ~/Documents are affected, and commands and scripts will fail when run on one of the most important and active directories on most macOS systems.
Not only that, but all Macs using iCloud Drive, irrespective of their Optimize Mac Storage setting, provide user access to folders shown in iCloud Drive which are not present in its file system path of ~/Library/Mobile Documents/com~apple~CloudDocs/
A shell script which, for example, backed up the contents of iCloud Drive to a local NAS drive could not rely on backing up the contents of ~/Library/Mobile Documents/com~apple~CloudDocs/, but would also need to back up other directories within ~/Library/Mobile Documents/ Determining which other directories remains a problem, as Apple doesn’t document how macOS selects those to be presented to the user in iCloud Drive.
One solution to some of these problems could involve either the eviction from local storage of some or all files stored in iCloud, or their download. Eviction is almost instantaneous, so long as a file is not open locally, but there is no user-accessible or shell command to accomplish that. Downloading could take a very long time – hours in the worst case – and could exceed local storage capacity.
Apple’s own most robust tool for locating files, the Finder alias, is broken by iCloud. Here’s a simple test that you can try to demonstrate this:
- select any document in your iCloud Drive, or iCloud-based Documents folder;
- make an alias to that document;
- move the alias to local storage, in your Documents folder if local, or elsewhere if not;
- using Cirrus, evict the folder containing the document to which you now have an alias;
- if macOS won’t evict that document, repeat the process with another iCloud document, and evict the folder again;
- double-click on the alias(es) to open the document(s).
Although opening an alias should trigger the linked document to be downloaded, if the alias opens before the download completes you will see an error message not that the document is still being downloaded, not that the file you have tried to open doesn’t exist, but that “You don’t have permission.”
Inevitably, all hard and symbolic links made to evicted files are also broken by their eviction.
Faced with the problems posed by iCloud, a lot of commands, shell scripts and other scripting becomes inordinately complex, and in some cases impossible. Apple needs to continue to evolve the iCloud interface, making it consistent with the fundamental needs of commands and shell scripts. If it doesn’t, but continues to converge with iOS, it will undermine macOS itself.