1. 程式人生 > >靠!安裝了macOS Catalina(10.15.4)後,檔案系統都亂套了

靠!安裝了macOS Catalina(10.15.4)後,檔案系統都亂套了

最近閒來無事,決定將我的兩臺apple電腦升級成最新的蘋果系統(macOS Catalina),當然,由於以前升級過多次mac系統,所以毫不猶豫從app store下載了最新的macOS Cetalina系統,當然,下載很快,安裝也很快,過程就不說了,so easy。
1. 到底發生了什麼事

不過安裝完後,發生了一件不可思議的事,進入硬碟,發現硬盤裡只有如下5個目錄。my god,我的其他資料夾哪裡去了?難道升級時給我格式化了?

 

 轉念一想,Apple應該不會這麼變態,否則蘋果總部應該早都被自己的使用者給踏平了。於是立刻上網查是怎麼回事,很過有了結果。原來從Catalina版本開始,Apple為了實現自己更安全的目的,將硬碟分成了兩個卷(以前是一個卷),一個是系統卷,一個是資料卷。從下圖所示的磁碟工具中就可以看出這一點。

 

這有些類似於Windows的邏輯磁碟,不過與Windows不同,Catalina的系統卷和資料卷是共享整個磁碟的,只是進行了邏輯隔離。在預設情況下,系統卷只允許作業系統本身來寫檔案,對於其他使用者(包括root使用者)都是隻讀的。也就是說,使用sudo命令也不能向系統卷寫入任何資料。

2. 我的檔案到哪裡去了呢?

現在關鍵的問題是,我的資料夾到哪裡去了呢?其實Catalina會將使用者自己建立的資料夾都放到如下的目錄:
/Users/Shared/Relocated\ Items/Security

如果你的mac系統是中文狀態,那麼該目錄就是下圖所示的目錄:

 

切換到該目錄,就會看到自己建立的所有的目錄和相關檔案。

這下放心了,只要檔案都在就好,那麼緊接著有面臨另外一個鬧心的問題,檔案是都在,但路徑全都變了,這就意味著以前設定的環境變數、word、excel、webstorm、goland等工具的開啟歷史已經沒有意義了,所有的路徑都需要重新設定,所有的檔案都需要重新開啟。天啊,我為什麼要升級呢!

3. 恢復以前的目錄結構

於是首先想到,是否將這些目錄和檔案移動到資料卷,路徑是否會恢復呢?說做就做。

從磁碟工具中資料卷的裝載點可以看到,資料卷的物理目錄是/System/Volumes/Data,於是立刻切換到該目錄,預設是空。

現在使用下面的命令將原來的目錄移動到資料卷根目錄(假設有一個名為test的目錄要移動)。

sudo mv /Users/Shared/Relocated\ Items/Security/test /System/Volumes/Data

如果要移動其他目錄,只要將test修改為相應的目錄名即可。注意,這裡必須用sudo,普通使用者沒有寫許可權。

注意:如果只在資料卷中移動資料,速度非常快,因為並不是真的移動的資料,而只是改變了目錄的位置。

將所有的目錄移動到/System/Volumes/Data後,會發現,目錄並沒有像期望的一樣恢復到原來的樣子,而是所有的目錄前面都加了一個/System/Volumes/Data,也就是說,變成了/System/Volumes/Data/test。看樣子要想其他法子了。

有網友提供的方法是將目錄和檔案直接移動到系統卷的根目錄,這樣就會恢復原貌了。這個方法當然可行,不過將資料從資料卷移動到系統卷,是非常費時的,因為這時真正的移動資料。而且系統卷要想寫入資料,需要做特殊處理(一會再說),比較麻煩。而且以後也無法使用一般的方法在系統卷根目錄新增任何目錄和檔案,感覺也比較彆扭。

我認為最好的方式是檔案和目錄仍然放在資料卷,而在系統卷根目錄建立指向資料卷相應目錄的軟連結,這樣以後再建立新目錄和檔案時,只要在資料卷完成即可。如果哪個檔案或目錄要通過根(/)訪問,可以在系統卷的根目錄建立一個軟連結,這樣才是是魚和熊掌可兼得之法。

不過系統卷預設即使使用root使用者也無法寫入檔案,不過可以將安全監測關掉。具體方法如下:

1. 重啟mac電腦,按著Command + R,等待進入安全模式;
2. 進入安全模式後,在上方選單開啟終端,然後執行csrutil disable命令關掉SIP(系統完整性保護),重啟電腦,正常進入系統;
3. 在終端執行sudo mount -uw / 命令將系統卷根目錄設為可寫狀態;

經過這3步,系統卷根目錄已經可寫了,但仍然需要使用sudo命令。如果操作完,想重新開啟SIP,可以再次進入安全模式,然後執行csrutil enable 命令即可,當然,不開啟也沒問題。現在假設資料卷有一個名為backup的目錄,為backup在系統卷根目錄建立軟連結的方法如下:

首先在終端進入系統卷根目錄,然後執行下面的命令
sudo ln -s /System/Volumes/Data/backup backup

為其他目錄在系統卷根目錄建立軟連線的方法類似。ok,現在我們可以為需要通過系統卷根目錄訪問的目錄和檔案建立軟連結了,都搞定後,我們會發現所有的路徑都恢復正常了。

4. 編譯程式又出錯了

如果你是普通使用者,那麼到這裡就完全搞定了,不過對於程式設計師來說,還遠遠沒有結束。由於我要使用go語言開發相關專案,於是試一試go語言是否可以編譯通過,結果.....,竟然輸出了下面的錯誤:

_cgo_export.c:3:10: fatal error: 'stdlib.h' file not found

這個錯誤我以前遇到過,是由於/usr/local目錄中沒有stdlib.h檔案導致的,在上一個macOS版本中,可以在磁碟上搜索macOS_SDK_headers_for_macOS_10.14.pkg檔案,然後安裝即可。不過在Catalina中,並沒有macOS_SDK_headers_for_macOS_10.14.pkg檔案,當然macOS_SDK_headers_for_macOS_10.15.pkg也沒有。不過在/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk目錄下卻發現了已經安裝好的相應檔案。

注意:如果沒有該目錄或相關檔案,可以使用 xcode-select --install命令安裝

這裡又要用到軟連結了,其實go使用cgo編譯時,會到如下兩個目錄搜尋相關檔案:
/System/Library/Frameworks/CoreFoundation.framework
/System/Library/Frameworks/Security.framework

所以只要通過軟連結,將相關的目錄和檔案連結到這兩個目錄即可,於是有了如下的解決方案:

在終端進入/System/Library/Frameworks/CoreFoundation.framework目錄,然後執行下面兩條命令:
sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers Headers

sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/CoreFoundation.framework/Versions/A/Modules Modules

再進入/System/Library/Frameworks/Security.framework目錄,然後執行下面兩條命令:
sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Security.framework/Headers Headers

sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Security.framework/Modules Modules

完成以上步驟後,新系統就一切恢復如常了,真是虛驚一場。最後建議:使用者的資料最好還是放在資料卷中,如果非要通過系統卷的根(/)訪問,可以在根目錄建立軟連結,但不要忘了開啟SIP哦!