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

推荐订阅源

D
DataBreaches.Net
S
Schneier on Security
T
The Exploit Database - CXSecurity.com
Webroot Blog
Webroot Blog
AI
AI
P
Palo Alto Networks Blog
Attack and Defense Labs
Attack and Defense Labs
WordPress大学
WordPress大学
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
Spread Privacy
Spread Privacy
T
Tor Project blog
罗磊的独立博客
小众软件
小众软件
S
Security Affairs
酷 壳 – CoolShell
酷 壳 – CoolShell
量子位
Apple Machine Learning Research
Apple Machine Learning Research
T
Threatpost
NISL@THU
NISL@THU
博客园_首页
PCI Perspectives
PCI Perspectives
大猫的无限游戏
大猫的无限游戏
IT之家
IT之家
N
News and Events Feed by Topic
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Forbes - Security
Forbes - Security
博客园 - 叶小钗
D
Darknet – Hacking Tools, Hacker News & Cyber Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
L
LINUX DO - 热门话题
T
Threat Research - Cisco Blogs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
腾讯CDC
Security Latest
Security Latest
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Cloudflare Blog
A
About on SuperTechFans
爱范儿
爱范儿
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
TaoSecurity Blog
TaoSecurity Blog
宝玉的分享
宝玉的分享
G
GRAHAM CLULEY
雷峰网
雷峰网
F
Full Disclosure
I
Intezer
Cloudbric
Cloudbric
博客园 - 三生石上(FineUI控件)
U
Unit 42

Homepage on Yihui Xie | 谢益辉

Bye, Stack Overflow - Yihui Xie | 谢益辉 Converting testthat Tests to testit - Yihui Xie | 谢益辉 Reflections on AI-assisted Programming - Yihui Xie | 谢益辉 Preliminary Support for Typst in knitr - Yihui Xie | 谢益辉 R.I.P., Tomas Kalibera - Yihui Xie | 谢益辉 An Introduction to xfun - Yihui Xie | 谢益辉 tinyimg: An R Package for Compressing Images - Yihui Xie | 谢益辉 The Surprising Slowness of `textConnection()` in R - Yihui Xie | 谢益辉 A CDN-backed CTAN Mirror: `tlnet.yihui.org` - Yihui Xie | 谢益辉
TinyTeX on macOS: No More Messing with `/usr/local/bin` - Yihui Xie | 谢益辉
Yihui Xie · 2026-03-27 · via Homepage on Yihui Xie | 谢益辉

If you have ever installed TinyTeX on a relatively recent macOS system, you might have seen an admin password prompt pop up out of nowhere. What was TinyTeX doing behind the scenes? Well… honestly, something it shouldn’t have been doing. Issue #463 by r2evans gave me a thorough and well-deserved lecture on it, and I’ve finally fixed it in PR #489.

How we got here?

I should start with an apology. The old behavior was my fault, born from blindly following a practice I picked up from Homebrew years ago without keeping up with how things evolved.

In the early days of Homebrew, it would create symlinks to /usr/local/bin, and back then (pre-Catalina, before 2019 or so) this directory was writable by default on macOS. When Apple tightened its permissions so that /usr/local/bin was no longer writable without sudo, Homebrew’s workaround was to ask users to sudo chown the directory. I followed this approach blindly when I first built TinyTeX’s PATH setup—adding a chown -R <user>:admin /usr/local/bin step via osascript, followed by tlmgr path add to create symlinks from /usr/local/bin/ into TinyTeX’s bin directory in the user’s home folder (~/Library/TinyTeX/bin/*/).

What I failed to notice was that Homebrew itself eventually moved on: on Apple Silicon Macs, it switched to /opt/homebrew, and the current Homebrew installer creates /etc/paths.d/homebrew to register its bin path, relying on macOS’s /usr/libexec/path_helper to incorporate it into PATH at shell startup. (It also instructs users to add eval "$(brew shellenv)" to ~/.zprofile for the full environment—PATH, MANPATH, INFOPATH, and a few Homebrew-specific variables.) I kept using the old chown trick long after it had become outdated and insecure. I should have updated TinyTeX’s approach at the same time. I’m sorry it took this long.

What was the problem?

The old approach had two issues from a security standpoint:

  1. Recursive chown on unrelated files. Running chown -R <user>:admin /usr/local/bin recursively changes the ownership of everything in that directory to the current user. Changing the ownership of files unrelated to TinyTeX is overreaching and hard to undo (you’d need to remember what the original owners were).

  2. Symlinks from a system directory into a user’s home folder. Running tlmgr path add places symlinks from /usr/local/bin/ into one particular user’s home directory. If that user’s home directory is unavailable or the TinyTeX installation moves, those symlinks become stale for anyone on the system who relies on /usr/local/bin. It also means a system-wide directory now depends on a single user’s private files, although I guess in most cases, you are the only user of your macOS.

r2evans put it plainly: “No R package should ever automatically/directly change permissions on a file/directory outside of the user’s home directory.” Hard to argue with that.

What’s the fix?

macOS provides /etc/paths.d/ as a way to register additional directories for inclusion in PATH. Each file there contains one path per line, and /usr/libexec/path_helper picks them up automatically when a shell starts. Writing a single file there is narrowly scoped: it doesn’t touch any existing binary, doesn’t change any permissions, and doesn’t create any cross-user symlinks. It’s exactly what Homebrew does today with /etc/paths.d/homebrew—and it’s what TinyTeX should have been doing all along.

So the new behavior on macOS is:

  • If /usr/local/bin is not writable (the default on modern macOS): TinyTeX writes its bin directory path to /etc/paths.d/TinyTeX via sudo (still using osascript, since /etc/paths.d/ does require admin privileges to write). No chown, no symlinks, no changes to any existing files. The old code that orchestrated the chown -R dance is gone entirely.

  • If /usr/local/bin is writable (meaning you previously went through the old setup): TinyTeX falls back to the old tlmgr path add behavior. I didn’t want to force existing users through another sudo prompt for something they’ve already set up—but I’d encourage you to clean that up (see below).

The same logic applies in both the R functions (e.g., tlmgr_path()) and the shell installer (install-bin-unix.sh). On Linux and Windows, nothing changes.

A few smaller improvements came along for the ride:

  • Before running the osascript command (which triggers the password prompt), TinyTeX now prints a message telling you exactly what sudo command it’s about to run, so the password dialog no longer comes out of nowhere.
  • If the sudo operation fails (e.g., you cancelled the password prompt), TinyTeX emits a message with the command you can run manually in your Terminal if you want.
  • The .sh installer gained a --no-path flag to skip PATH manipulation altogether, on any OS. For tinytex::install_tinytex(), the existing add_path = FALSE argument serves the same purpose.

What does this mean for you?

Fresh macOS installs: The next time you run tinytex::install_tinytex(), you’ll see a message in the R console telling you the sudo command that is about to run (writing TinyTeX’s bin path to /etc/paths.d/TinyTeX), followed by the usual password dialog. No files in /usr/local/bin are touched.

Existing users—please consider cleaning up: If you previously ran through the old setup, your /usr/local/bin is likely writable and TinyTeX is still using the old tlmgr path add symlink approach. I’d encourage you to restore the original ownership of /usr/local/bin and let TinyTeX switch over to the new approach. Based on what I can tell from stat -f "%Su:%Sg" /usr/local on my own machine, the command to restore it should be:

sudo chown root:wheel /usr/local/bin

(Note: some systems may have root:staff as the original group; you can check with ls -la /usr/local to see what makes sense for your setup.)

That restores the directory itself, but our chown -R also changed the ownership of files inside it—and we owe a note on those too. On my own Apple Silicon machine, I can see two kinds of files in /usr/local/bin: tools placed there by official macOS app installers (e.g., R and Rscript, which are root:admin), and tools I installed myself (which are <user>:admin and were not affected by TinyTeX’s chown). So the practical restoration for installer-placed tools is sudo chown root:admin, not root:wheel. After inspecting with ls -la /usr/local/bin, you can restore each affected file individually, e.g.,

sudo chown root:admin /usr/local/bin/R /usr/local/bin/Rscript

After doing this, /usr/local/bin will no longer be writable, and on the next call to tlmgr_path('add') TinyTeX will automatically write /etc/paths.d/TinyTeX instead. You may also want to first remove the old symlinks that tlmgr path add created:

tlmgr path remove

And then re-add TinyTeX’s path with the new approach:

if (packageVersion('tinytex') < '0.59')
  install.packages('tinytex')
tinytex::tlmgr_path('add')

Again, my sincere apologies for letting this linger for so long. I should have followed Homebrew’s lead when it moved to /etc/paths.d/ years ago. Better late than never, I suppose.

My thanks to r2evans for the patient and detailed report. This change is part of tinytex v0.59, which just arrived CRAN last night.

If you run into any surprises with the new PATH setup on macOS, please file an issue. Thanks!

Donate

As a freelancer (currently working as a contractor) and a dad of three kids, I truly appreciate your donation to support my writing and open-source software development! Your contribution helps me cope with financial uncertainty better, so I can spend more time on producing high-quality content and software. You can make a donation through methods below.

  • Venmo: @yihui_xie, or Zelle: [email protected]

  • Paypal

    • If you have a Paypal account, you can follow the link https://paypal.me/YihuiXie or find me on Paypal via my email [email protected]. Please choose the payment type as “Family and Friends” (instead of “Goods and Services”) to avoid extra fees.

    • If you don’t have Paypal, you may donate through this link via your debit or credit card. Paypal will charge a fee on my side.

  • Other ways:

    WeChat Pay (微信支付:谢益辉) Alipay (支付宝:谢益辉)
    WeChat Pay QR code Alipay QR code

When sending money, please be sure to add a note “gift” or “donation” if possible, so it won’t be treated as my taxable income but a genuine gift. Needless to say, donation is completely voluntary and I appreciate any amount you can give.

Please feel free to email me if you prefer a different way to give. Thank you very much!

I’ll give back a significant portion of the donations to the open-source community and charities. For the record, I received about $30,000 in total (before tax) in 2024-25, and gave back about $15,000 (after tax).