Reading view

There are new articles available, click to refresh the page.

Links, aliases and the decline of paths

One of the fundamental requirements of any decent operating system and its primary file system is to provide objects that link to files and directories in storage. These allow code and users to access those files and folders indirectly, by referencing them from elsewhere. In most systems there are two methods of achieving this, by referencing the directory path and name of the file/folder, or using a reference to an identity number unique to that file system and part of that file’s attributes, normally the inode number. These form symbolic and hard links respectively.

Symlinks

linksetc3

A symlink is a separate file containing the path to the file or folder that it links to. It thus has its own File System Object, and its own tiny data containing the path to the original. This works well as long as that path is preserved in its entirety. The inode of the original file is unaware of any symlinks to it, so deleting the original file also breaks every symlink to that file.

Symlinks are easily created in Terminal using a command like
ln -s /Users/myname/Movies/myMovie.mov /Users/myname/Documents/Project1/myNewMovie.mov
which creates a tiny file myNewMovie.mov containing the path /Users/myname/Movies/myMovie.mov referring to the file it links to.

You can’t create symlinks using the Finder but can using third-party apps, and they should now work fully with QuickLook thumbnails and previews. They essentially take no space on disk. Paths used can be shorter and relative, allowing an enclosing folder to be moved within that volume, which would break a full absolute path. They can also specify files on other volumes, so long as the path to them remains correct.

Paths in symlinks work most reliably in the macOS SSV, as it’s both structured and static. Although the disciplined user can use them effectively in their Home folder, they are prone to unintended effects such as the renaming of an intermediate directory, moving any component in the path, and even changing the Unicode normalisation of a character in the path. As symlinks only contain a path, there’s no fallback to try resolving a broken path, making them inherently fragile, not robust.

Hard links

linksetc2

In APFS, a hard link is actually a single file, with one File System Object, that has two or more references in the form of Siblings that are associated with the file inode. That object has a single set of File Extents, so each of the siblings refers to exactly the same file and data, although siblings will normally have different paths. In the object, the reference count equals the number of siblings; when siblings are deleted, that count is decremented, and the object is only removed when the count reaches zero.

Hard links are easily created in Terminal using a command like
ln /Users/myname/Movies/myMovie.mov /Users/myname/Documents/Project1/myNewMovie.mov
to create a new hard link named myNewMovie.mov to the original myMovie.mov.

You can’t create hard links in the Finder, and because they use a single set of File Extents, they essentially take no space on disk.

Hard links look and work exactly like the original, and can be moved around freely within the same volume as they’re not dependent on paths. Copy one to another volume, though, and the copy will be a complete unlinked file. Hard links to files and to directories were one of the essential ingredients of Time Machine backups on HFS+, but as APFS doesn’t support directory hard links, Time Machine now has to use a different backup format for storage on APFS.

Aliases and bookmarks

Aliases originated in System 7, when Mac OS lacked the BSD/Unix features that were to come in Mac OS X. At that time, paths were seldom used, making symlinks implausible, so the original Finder alias was instead built on the equivalent of an inode number. They have evolved into a combination offering path information and inode number that should be able to resolve links that would break the path in symlinks, and can extend to other volumes, unlike hard links.

Despite their robustness and versatility, macOS provides no bundled command tools for the creation of aliases or their resolution into paths, making them of no use in shell scripts or the command line, although the free alisma addresses these. Neither have they been integrated into APFS as distinct objects in the file system, where they’re just another file.

Bookmarks are a variant of aliases intended to be used in files for similar purposes. For example, the list of files shown in the Open Recent menu command in apps is assembled from a file containing bookmarks to each of those documents. Most lists of apps and files built by Launch Services and other sub-systems are similarly reliant on bookmarks.

Demonstration

To demonstrate how these three different types of link behave, create a folder in your Home Documents folder (~/Documents), and copy a test document into that. Next to that file, create another folder named links, and within that create a symlink (using a full absolute path), a hard link, and an alias to the original file.

links

Copy the file containing the links to another volume, and note how the hard link becomes a separate local file instead of a link, but the symlink and alias continue to link to the original, whose path is unchanged.

Rename the folder enclosing the test document and links folder, and note how the symlink is then broken, although QuickLook may still show a cached thumbnail for it. Note how this also breaks the copy of the symlink on the other volume, as the path used by both of them no longer exists.

Finally, move the folder of links to be alongside that containing the original document, in the ~/Documents folder, and note how the symlink is broken there too.

Of the three types of link, the only one that proves robust to all these changes is the alias.

A brief history of the Finder Alias

It wasn’t until System 7 in 1991 that the Mac gained any feature that let the user create links to files or folders. Without a command shell, Unix traditions of symbolic and hard links weren’t available. Apple belatedly added what it termed an alias, created using the Make Alias command in the Finder’s File menu. This made a document-like object bearing the name of its original with alias appended, displayed in italics to distinguish it from the original. To help users locate the original file for an alias, the Finder’s Get Info dialog gained a button to Find Original, later moved to the File and contextual menus.

Later versions of classic Mac OS added refinements to this transformative feature, including the selection of a new target for a broken alias, creation by drag-and-drop of a file or folder with the Command and Option keys held, and a distinctive arrow badge to both the item’s icon and the pointer during drag-creation.

Internally, the alias was a small file of less than 5 KB size containing opaque data with more information than just the path to the original. Aliases were designed to support free movement within the same file system, at the time an HFS volume (or partition, as they’re the same in HFS and HFS+).

Aliases transferred across to Mac OS X, where the more adventurous could open Terminal and create both symbolic and hard links instead. It has remained a sign of the lasting schism between the GUI and Unix internals of Mac OS X that there are no standard command tools supporting Finder aliases, and there’s no way to create or maintain symbolic or hard links in the Finder.

Something happened to aliases when they transitioned into Mac OS X, and their size started to rise steadily until they reached 1-5 MB in El Capitan.

aliastiger104

Back in Mac OS X 10.4 Tiger they were still fairly small, this one at 48 KB. Note the Select New Original… button in the Get Info dialog.

Aliases were all very good for the user, but OS X needed something similar that could be stored in property lists and other files, so the alias format was rejigged into more generalised form as the bookmark, introduced in OS X 10.6 in 2009. In early 2012 with 10.7.3, bookmarks could be security-scoped with permission on a per-app or per-document basis, to enable their use with the app sandbox. By OS X 10.9 Mavericks in 2013, bookmarks were in widespread use throughout the system.

aliaselcap1011

In El Capitan (2015), bookmark size often reached 1 MB, while the Select New Original… button remained the same in the Get Info dialog.

macOS Sierra brought a major revision to both aliases and bookmarks, reducing their size substantially, but bringing other problems. As late as 10.12.1 they were still having problems resolving some links. The end result was worth the struggle, though, as they have since become more robust than ever, with a typical size of only 1 KB, making them almost as efficient as symbolic links.

Although aliases and bookmarks are still intended to be treated as opaque, their contents have become more accessible. Among the useful values each contains are:

    • _NSURLPathKey gives the full path to the file,
    • _NSURLFileIDKey gives the inode number of the file,
    • _NSURLBookmarkURLStringKey gives the file’s full URL,
    • NSURLCreationDateKey gives the file’s creation timestamp,
    • NSURLIsRegularFileKey indicates whether it’s a normal file,
    • NSURLIsPackageKey indicates whether it’s a package rather than a file,
    • _NSURLBookmarkSecurityScopeCryptoKeyKey is used if this is a Security-Scoped Bookmark, most used with sandboxed apps.

I even have a couple of utilities that work with them. Among the many features of Precize is the ability to generate bookmarks, and to analyse and resolve them. For those who want to bridge the divide between the GUI and command line, alisma is a tool that can both create aliases and resolve them to paths. Finally, Alifix helps you refresh and identify broken aliases.

❌