Mac 的 /tmp 是我的練習場:重開機就清空,隨便玩都不怕
我有個習慣:想試一個沒把握的指令、想 clone 別人的 repo 來翻翻、或是下載了一包不知道裝什麼的壓縮檔,第一步都是先 cd /tmp。
原因很簡單,這個資料夾重開機就會清空。在裡面怎麼亂玩都沒關係,玩完也不用收,下次開機它自己就乾淨了。
今天順手 ls -ld /tmp 看了一下,發現它其實不是一個資料夾:

箭頭 -> 的意思是 /tmp 只是一條捷徑(symbolic link),真正的資料夾在 /private/tmp。這篇就從這行輸出講起,順便聊聊我怎麼拿它當練習場。
拆開這行 ls
lrwxr-xr-x@ 1 root wheel 11 Jun 25 10:29 /tmp -> private/tmp
一格一格看:
- 開頭的
l:這是 link,不是資料夾。資料夾的話這格會是d。 - 權限後面的
@:代表它身上掛著 extended attributes(延伸屬性)。用xattr -sl /tmp可以看到是com.apple.rootless,這是 SIP(系統完整性保護)的標記,意思是這條捷徑屬於系統檔案,連 root 都不能改。 root wheel:擁有者是 root,群組是 wheel。11:捷徑的大小是 11 bytes。捷徑裡只存了一個路徑字串,private/tmp剛好 11 個字元,用echo -n private/tmp | wc -c算一下就知道。Jun 25 10:29:跟/bin/ls這些系統檔案的時間戳一模一樣。這條捷徑是 macOS 本身的一部分,不是誰後來建的。
想看真正的資料夾,在路徑後面多加一個斜線,ls 就會跟著捷徑走進去:
$ ls -ld /tmp/
drwxrwxrwt 115 root wheel 3680 Sep 23 16:16 /tmp/
這次開頭變成 d 了。權限 rwxrwxrwt 前面代表所有人都能讀、能寫、能進去,最後那個 t 叫 sticky bit:大家都能在裡面放東西,但只能刪自己的。這台 Mac 上每個帳號、每支背景程式都在共用 /tmp,就是靠這個 t 才不會互相刪到對方的檔案。
重開機真的會清空嗎?我比對了開機時間
「/tmp 重開機就清空」這句話大家都這樣講,這次想實際驗證一下。我沒有真的去重開機,而是比對兩個時間:這次開機的時間,跟 /private/tmp 這個資料夾的建立時間。
# 這次開機的時間
sysctl kern.boottime
# { sec = 1789701419, usec = 548252 } Fri Sep 18 11:16:59 2026
# /private/tmp 這個資料夾的建立時間(%SB 是 birth time)
stat -f '%SB' /private/tmp
# Sep 18 11:17:15 2026
資料夾本身的建立時間,只比開機晚 16 秒。所以它不只是「把裡面的東西刪光」,是整個資料夾在開機時重新建立一次。我把裡面 113 個項目的建立時間也全部掃過,沒有一個早於這次開機。
以前的 Mac OS X 把這件事寫得很直白。Apple 開源的開機腳本 rc.cleanup(檔頭寫著 Copyright 2002 Apple Computer)裡有這一段:
# Clean out /private/tmp.
if [ -d /private/tmp ]; then
# (清掉上次殘留 _tmp_ 的部分略過)
echo -n " /private/tmp"
mv /private/tmp /private/_tmp_
(chflags -R nouchg /private/_tmp_ && rm -rf /private/_tmp_) &
fi
mkdir -m 1777 /private/tmp
先把整個資料夾改名成 _tmp_,丟到背景慢慢刪,再立刻建一個全新的 /private/tmp。這樣開機不用等舊檔案刪完,新的 /tmp 馬上就能用。1777 就是前面看到的 rwxrwxrwt,最前面那個 1 代表 sticky bit。
現在的 macOS 改由 launchd 負責開機,這支腳本已經不在了,我也沒找到現在是哪段程式在做這件事。不過從建立時間看,結果跟當年一樣:整個資料夾重建。
對照組是 /var/tmp:
stat -f '%SB' /private/var/tmp
# Jun 25 10:29:03 2026
它三個月前就在了,9 月 18 日那次開機並沒有動到它。macOS 的 man hier 對 /var/tmp 的說明是:
temporary files that are kept between system reboots
也就是「重開機會保留的暫存檔」。名字很像,一個會清一個不會,練習的時候別放錯地方。
不重開機,放三天沒碰也會被清
那只要不關機,是不是就能一直放?也不行。macOS 有一支每天跑的清理工作,設定檔在 /System/Library/LaunchDaemons/com.apple.tmp_cleaner.plist,用 plutil -p 打開來看:
"ProgramArguments" => [
0 => "/usr/libexec/tmp_cleaner"
]
"StartCalendarInterval" => {
"Hour" => 0
}
每天凌晨 0 點那個時段會跑 /usr/libexec/tmp_cleaner。它是一支 shell script,可以直接 cat 出來看,關鍵是這幾行:
daily_clean_tmps_dirs="/tmp" # Delete under here
daily_clean_tmps_days="3" # If not accessed for
args="-atime +$daily_clean_tmps_days -mtime +$daily_clean_tmps_days"
args="${args} -ctime +$daily_clean_tmps_days"
白話翻譯:/tmp 底下的檔案,如果最後讀取、最後修改、最後變更屬性的時間全部超過 3 天,就刪掉。放了超過 3 天的空資料夾也會一起清掉。
還有一點跟 cron 不一樣:0 點的時候 Mac 如果在睡覺,launchd 會等下次喚醒再補跑。man launchd.plist 是這樣寫的:
Unlike cron which skips job invocations when the computer is asleep, launchd will start the job the next time the computer wakes up.
所以筆電蓋起來過夜也躲不掉。整理起來,一個丟進 /tmp 的檔案大概會有這幾種下場:
flowchart TB
A["在 /tmp 建立一個檔案"] --> B{"接下來發生什麼事?"}
B -->|"重開機"| C["開機時 /private/tmp<br/>整個重新建立<br/>檔案消失"]
B -->|"連續 3 天沒讀、沒改"| D["tmp_cleaner 凌晨 0 點刪掉<br/>Mac 在睡覺就等喚醒後補跑"]
B -->|"你想留下來"| E["搬到 ~/ 底下<br/>才算真的存起來"]
冷知識:這支腳本的變數名是從 FreeBSD 搬來的
tmp_cleaner 明明是一支獨立的小程式,變數卻都叫 daily_clean_tmps_ 開頭,看起來像是從哪裡搬來的。
man tmp_cleaner 的 HISTORY 只有一行:
tmp_cleaner first appeared in macOS 14.0
它是 macOS Sonoma 才出現的新程式,但內容很舊。舊版 macOS 用的是 periodic 這套每日維護機制,其中清 /tmp 的腳本叫 /etc/periodic/daily/110.clean-tmps。Apple 開源的版本檔頭寫著:
# $FreeBSD: src/etc/periodic/daily/110.clean-tmps,v 1.13 2004/02/28 04:58:40 ache Exp $
這是直接從 FreeBSD 搬來的。它的設定檔 periodic.conf 裡有這三行:
daily_clean_tmps_enable="YES" # Delete stuff daily
daily_clean_tmps_dirs="/tmp" # Delete under here
daily_clean_tmps_days="3" # If not accessed for
跟現在的 tmp_cleaner 比一比,變數名一樣,連行尾註解「Delete under here」「If not accessed for」都一字不差,-atime、-mtime、-ctime 三個條件也是原封不動。daily_ 這個前綴,是它當年身為 periodic「每日任務」留下來的名字。我這台 macOS 26 已經沒有 /etc/periodic 資料夾了,但這三天的規則還活在 tmp_cleaner 裡。
我拿 /tmp 來做什麼
知道它會自己清乾淨之後,/tmp 就變成很放心的練習場。幾個我覺得特別適合的用法:
練習有破壞力的指令。 rm、mv、find -delete 這類指令,萬用字元會刪到哪些檔案,先在 /tmp 做一個假資料夾試過再說:
mkdir -p /tmp/play && cd /tmp/play
touch a.txt b.txt c.log
rm *.txt # 確認只刪到 .txt,再拿去真正的資料夾用
clone 別人的 repo 來翻翻。 只是想看看某個專案怎麼寫的,不打算長期留著,就丟到 /tmp。加 --depth 1 只抓最新版本,比較快:
cd /tmp && git clone --depth 1 https://github.com/withastro/astro.git
看專案產生器會生出什麼。 npm create 這類 scaffolding 工具會一口氣生出一堆檔案。想先看看它生了什麼,就在 /tmp 跑一次,不會弄髒自己的專案資料夾。
看壓縮檔裡到底裝什麼。 從網路上抓的壓縮檔,先解到 /tmp 裡看一眼:
mkdir /tmp/peek && tar -xzf ~/Downloads/something.tar.gz -C /tmp/peek
懶得想資料夾名稱。 用 mktemp -d 每次都會拿到一個不重複的新資料夾:
cd "$(mktemp -d)"
要注意的是,macOS 上的 mktemp -d 不是建在 /tmp,而是建在 $TMPDIR,路徑長得像 /var/folders/86/…/T/tmp.y7ks3XlAK6。這是每個使用者自己的暫存區,下一節會講到它。
用之前要知道的三件事
/tmp 是全機共用的,別放祕密。 macOS 預設的 umask 是 022,意思是你在 /tmp 建的檔案,其他帳號讀得到。密碼、token、.env 這類東西別丟進來。需要私人的暫存空間就用 $TMPDIR:
$ ls -ld "$TMPDIR"
drwx------@ 2085 bobochen staff 66720 Sep 23 16:21 /var/folders/86/…/T/
權限是 rwx------,只有你自己進得去。
如果是自己寫程式要用暫存檔,也別把 /tmp 寫死。Apple 自己的 File System Programming Guide 就這樣講:
The primary directory (/tmp) is where most local files go, but you should never hardcode this path into your application.
用語言內建的函式去拿暫存資料夾就好,像 Node.js 的 os.tmpdir()、Python 的 tempfile.gettempdir(),在 macOS 上拿到的都是 $TMPDIR。
路徑有時候會顯示成 /private/tmp。 在 /tmp 裡用 pwd 會顯示 /tmp,但 pwd -P(顯示實際路徑)會顯示 /private/tmp。有些工具的錯誤訊息或輸出會印出 /private/tmp/...,那是同一個地方,不用緊張。
cd /tmp
pwd # /tmp
pwd -P # /private/tmp
/tmp 是練習場,不是沙盒。 重開機會清空,不代表在裡面跑東西比較安全。在 /tmp 執行的程式,權限跟在家目錄執行一模一樣,該讀得到的檔案它都讀得到。解壓縮來看看沒問題,來路不明的 script 就算放在 /tmp 也別執行。
冷知識:/tmp 其實橫跨了兩顆磁碟
macOS Catalina 開始,系統被切成兩個 volume:一個是唯讀的系統磁碟,一個是放你的資料的「Macintosh HD - Data」。Apple 的說明文件是這樣寫的:
macOS Catalina or later runs on a dedicated, read-only system volume called Macintosh HD. This volume is completely separate from all other data to help prevent the accidental overwriting of critical operating system files.
在終端機打 mount 也看得到,根目錄 / 被標成 sealed 跟 read-only:
/dev/disk3s3s1 on / (apfs, sealed, local, read-only, journaled)
/dev/disk3s1 on /System/Volumes/Data (apfs, local, journaled, nobrowse, protect, root data)
系統磁碟既然是唯讀的,/tmp 這種要讓大家隨時寫入的地方怎麼辦?答案藏在 /usr/share/firmlinks 這個檔案裡。打開來會看到一行:
/private private
firmlink 是 Apple 為了這種雙磁碟架構做的特殊連結,讓系統磁碟上的 /private 直接通到資料磁碟上的 private。所以一個寫進 /tmp 的檔案,實際上走了兩段路:
flowchart TB
A["/tmp<br/>系統磁碟上的捷徑<br/>唯讀、SIP 保護"] -->|"symlink"| B["/private/tmp"]
B -->|"firmlink"| C["資料磁碟上的 private/tmp<br/>真正可以寫入的地方"]
這也解釋了開頭那行 ls 的兩個細節:/tmp 身上的 com.apple.rootless 標記,跟它和 /bin/ls 一模一樣的時間戳,因為它就住在那顆唯讀的系統磁碟上,跟著 macOS 一起安裝、一起更新。
一句話總結
/tmp 是 Mac 送你的免洗練習場:重開機整個重建、三天沒碰半夜收走、全機帳號共用。拿它練手、翻別人的程式碼、看壓縮檔都很適合,只要記得一件事:想留下來的東西,記得搬回家目錄。
參考資料
man hier、man launchd.plist、man tmp_cleaner(在自己的 Mac 上就能讀)/usr/libexec/tmp_cleaner、/System/Library/LaunchDaemons/com.apple.tmp_cleaner.plist、/usr/share/firmlinks(本機檔案,macOS 26)- 舊版 Mac OS X 開機腳本 rc.cleanup、periodic 的 110.clean-tmps 與 periodic.conf(Apple 開源碼的 GitHub 鏡像)
- Apple Support:About the read-only system volume in macOS Catalina or later
- Apple Developer(封存文件):Where to Put Application Files