惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
C
Check Point Blog
B
Blog RSS Feed
G
Google Developers Blog
H
Help Net Security
博客园 - Franky
Blog — PlanetScale
Blog — PlanetScale
H
Hackread – Cybersecurity News, Data Breaches, AI and More
量子位
Recent Announcements
Recent Announcements
B
Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
D
DataBreaches.Net
小众软件
小众软件
T
The Blog of Author Tim Ferriss
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
Y
Y Combinator Blog
T
Tailwind CSS Blog
J
Java Code Geeks
MyScale Blog
MyScale Blog
雷峰网
雷峰网
有赞技术团队
有赞技术团队
博客园 - 聂微东

Lobsters

CIFSwitch: a non-universal Linux local root vulnerability RIPE NCC session fixation: poaching logins with an Atlas probe GNOME 2.20 but its Web Components Agentic Search for Context Engineering – Leonie Monigatti Garnix is shutting down [not OC] akashina.tngl.sh/jjc Concerning Emacs (and Jazz) Nitpicking the shell history scene in ‘Tron: Legacy’ What's cooking on SourceHut? Q2 2026 The tenth OpenPGP email summit Package managers that package package managers Clojure on Fennel part three: parsing WordPress at 23 Finding Miscompiles for Fun, Not Profit GitHub - creusot-rs/creusot: Creusot helps you prove your Rust code is correct. Announcing Rust 1.96.0 | Rust Blog A Love Letter to Neovim sqlite AGENTS.md Am I a Bad Friend? CSS vs. JavaScript • Josh W. Comeau Erlang Ecosystem Foundation - Supporting the BEAM community A brief note about slot access cost in Common Lisp Keyboard latency probe Rethinking the GNOME clipboard issues Back to the Building Blocks’ Building Blocks Tech Notes: Theseus: translating win32 to wasm Fast is better than slow Content-addressed Rust builds (or, what kache actually caches) Intent to Prototype: Embedding API Canada’s Bill C-22 and the security cost of collecting more data
A tale of two path separators
2026-06-17 · via Lobsters

I was reminded yesterday that macOS will happily let you create files that appear to have slashes in their name, as shown here by the Finder:

A Finder window with two entries. The first is a folder named 'a/b/c' (a slash b slash c), the second is a text file named 'x/y/z' (x slash y slash z).

I made the folder with the “New Folder” button in Finder, and the text file by saving it in TextEdit. Even though I understand how this works, it breaks my brain a bit every time.

If you didn’t know how this works, you could get a clue by running ls:

$ ls
a:b:c/     x:y:z.txt

The files have either colons or slashes in their name, depending on how you look at them.

I don’t understand all the nuances, but I know this is a side-effect of the fact that macOS has not one but two path separators: the slash (/) and the colon (:). The two separators are used in different contexts, and the system will translate between them as needed.

These two separators reflect the two parent systems of modern macOS: classic Mac OS and the Unix-like NeXTSTEP. When they were joined together, Apple’s engineers had to build a file system that was compatible with both the classic Mac’s file system (the Mac OS Extended File System, aka HFS+), and with NeXTSTEP’s file system (the Unix file system, aka UFS). Among other differences, these systems had different path separators: HFS+ used a colon, while UFS used a slash.

There’s a Usenix 2000 paper written by several Apple engineers which describes the problems of combining classic Mac OS and Unix in more detail. It actually describes exactly what we’re seeing with the Finder and ls:

[The translation layer] can create a user-visible schizophrenia in the rare cases of file names containing colon characters, which appear to Carbon applications as slash characters, but to BSD programs and Cocoa applications as colons.

AppleScript is where you’re most likely to encounter colons as path separators in modern macOS:

$ which osascript
/usr/bin/osascript

$ osascript -e 'tell application "Finder" to get (path to me)'
alias Phoenix SSD:usr:bin:osascript

This is likely because AppleScript goes back to System 7, which only had to care about HFS+ and colons. It can give you a UNIX- (or POSIX-) style path, but you have to ask for it explicitly:

$ osascript -e 'tell application "Finder" to get POSIX path of (path to me)'
/usr/bin/osascript

In 2017, Apple replaced HFS+ with the Apple File System, aka APFS, but these dual path separators remain. I can’t find any documentation to confirm it, but I assume that’s for backward compatibility reasons – picking a single path separator would break an enormous amount of software.

The “slashes in filenames” breaks my brain because I started programming after Unix-style filesystems had become totally dominant. In my mind, slash is the directory separator, and Windows is weird for using the backwards slash (\). In reality, file systems have used a variety of directory separators, and it’s only the current Unix hegemony that makes this seem weird. On another timeline, forward slashes in a filename would seem totally normal.