将 Mac 软件优雅的转移到移动硬盘里 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wangheng486
V2EX    macOS

将 Mac 软件优雅的转移到移动硬盘里

  •  
  •   wangheng486 1 月 25 日 2434 次点击
    这是一个创建于 89 天前的主题,其中的信息可能已经有所发展或是发生改变。

    AppPorts

    https://github.com/wzh4869/AppPorts 外置硬盘拯救世界!/ External drives save the world!

    一款专为 macOS 设计的应用程序迁移与链接工具。
    轻松将庞大的应用程序迁移至外部存储,同时保持系统无感运行。

    简介

    Mac 的内置存储空间寸土寸金。AppPorts 允许您一键将 /Applications 目录下的应用程序迁移到外部移动硬盘、SD 卡或 NAS ,并在原位置保留应用入口,让系统误以为应用仍在本地。

    对 macOS 系统而言,应用依然“存在”于本地,您可以像往常一样启动它们,但实际占用的却是廉价的外部存储空间。

    核心功能

    • 应用瘦身:一键将几十 GB 的大型应用(如 Logic Pro, Xcode, 游戏等)迁移至外置硬盘。
    • Contents 链接:采用 Contents 目录链接 方案,专为适配 macOS 机制设计。
      • 原理:在本地保留 .app 文件夹结构,仅将内部的 Contents 数据目录链接至外部存储。
      • 空间占用:本地仅保留文件夹索引信息,占用空间受文件系统块大小限制(通常可忽略不计)。
      • 兼容性:Finder 不会显示快捷方式小箭头,且支持 macOS 26 的 "App 菜单" 显示。
    • 安全机制
      • 自动识别并锁定 系统应用,防止误操作破坏系统。
      • 迁移前检测 运行状态,防止损坏正在运行的应用。
    • 随时还原:只需点击“还原”,即可将应用完整迁回本地磁盘,符号链接自动移除。
    • 现代 UI
      • 原生 SwiftUI 开发,丝滑流畅。
      • 完美适配 深色模式
      • 支持 中英双语,可随系统或手动切换。
    • 无障碍优化
      • VoiceOver 深度适配:支持列表行整体朗读、转子快捷操作。
      • 语义化界面:屏蔽装饰性图标干扰,状态标签支持清晰的语音播报。
      • 盲文支持:新增 Braille 语言选项,界面文字可直接显示为点字。
    • 全球化支持
      • 20+ 种语言支持
      • 本地化单位:文件大小会自动遵循当前语言的数字和单位格式习惯。
    • 快速检索:内置搜索栏,快速定位本地或外部应用。

    为什么选择 AppPorts ?

    相较于市面上其他方案,AppPorts 采用了独特的 Contents 链接 技术,兼顾了美观、兼容性与系统整洁度。

    方案 AppPorts 传统软链
    Finder 图标 原生 (无箭头) 有箭头 (快捷方式)
    Launchpad 完美索引 经常失效
    App 菜单 (macOS 26) 完美支持 不支持
    文件系统整洁度 极佳 (仅 1 个链接) 极佳 (仅 1 个链接)
    维护与还原 毫秒级 毫秒级

    截图

    欢迎页 主界面
    Welcome Main
    深色模式 语言切换
    Dark Lang

    安装与运行

    系统要求

    • macOS 14.0 (Sonoma) 或更高版本。

    下载安装

    请前往 Releases 页面下载最新版本的 AppPorts.dmg

    “AppPorts”已损坏,无法打开

    如果打开应用时遇到此提示(且系统建议移到废纸篓),这是因为应用没有进行开发者签名,被 macOS 的 Gatekeeper 机制拦截。 (注意:以下命令假设您已将 AppPorts 拖入 应用程序 文件夹) 您需要在终端运行以下命令来移除隔离属性,即可正常打开:

    xattr -rd com.apple.quarantine /Applications/AppPorts.app 

    权限说明

    首次运行时,AppPorts 需要 “完全磁盘访问权限” 才能读写 /Applications 目录。

    1. 打开 系统设置 -> 隐私与安全性
    2. 选择 完全盘访问权限
    3. 点击 + 号,添加 AppPorts 并开启开关。
    4. 重启 AppPorts 。
    25 条回复    2026-02-11 10:19:36 +08:00
    byby
        1
    byby  
       1 月 25 日
    既然这么好,为啥才 9 个 star
    wangheng486
        2
    wangheng486  
    OP
       1 月 25 日
    @byby 我也不知道哈哈哈,可能是之前没在别的地方发,我觉得还挺好用的
    BernieDu
        3
    BernieDu  
       1 月 25 日
    是在 application 创建一个空的 app 文件夹,文件夹内的内容是软连接到移动硬盘的 app 吧。这样的话拔掉移动硬盘会留下一堆无效内容,还不如直接在移动硬盘的 application 文件夹直接打开 app 啊
    xy19009188
        4
    xy19009188  
       1 月 26 日
    可以提个建议吗,app 除了按照首字母,还可以按照 app 大小进行排序
    tamarix666
        5
    tamarix666  
       1 月 26 日
    正好有这个需求,多谢 OP 。有个小问题:如果移动硬盘意外掉线,有没有修复机制呢?
    wangheng486
        6
    wangheng486  
    OP
       1 月 26 日
    @BernieDu 软件内可以直接删除“空的 app 文件夹”,这个软件起初就是为了“软连接”管理麻烦的问题,时间长了忘记哪个软件是在外置存储,做空的文件夹目的是为了 mac26 之前版本启动台软连接会出现不好看的快捷方式角标问题。
    wangheng486
        7
    wangheng486  
    OP
       1 月 26 日
    @xy19009188 感谢,我这边后期会试着加这个功能
    wangheng486
        8
    wangheng486  
    OP
       1 月 26 日
    @tamarix666 没有,这样比较复杂,暂时没有考虑这个问题。这个可以简单理解为一个“软连接”管理应用,只不过软连接实现比较像“软件真的就在内置存储一样”
    iamzuoxinyu
        9
    iamzuoxinyu  
       1 月 26 日
    支持 Playcover 的 ios 应用/游戏么,貌似有的游戏类的应用会检测 container 里的软链接。
    wangheng486
        10
    wangheng486  
    OP
       1 月 26 日
    @iamzuoxinyu 还真没试过 Playcover ...
    unneeded
        11
    unneeded  
       1 月 26 日
    原来还有映射 contents 这个方法,我之前映射.app ,经常在搜索框里搜到两个应用
    回头试试看,感谢分享
    wangheng486
        12
    wangheng486  
    OP
       1 月 26 日
    @xy19009188 已添加该功能
    wangheng486
        13
    wangheng486  
    OP
       1 月 26 日
    @unneeded 其实映射 contents 也会这样,软件目的就是不让旧版本的 macos 启动台出现软连接角标
    unneeded
        14
    unneeded  
       1 月 26 日
    @wangheng486 #13
    那我感觉可以优化一下,把目标文件夹中的".app"去掉,这样搜索框就不会搜到两个应用了
    unneeded
        15
    unneeded  
       1 月 26 日
    @unneeded #14
    甚至可以换成.framework 这种,这样还可以避免搜到内部的可执行文件
    unneeded
        16
    unneeded  
       1 月 26 日   1
    @unneeded #14 不过想了想似乎可以直接把目标目录加到排除列表里
    wangheng486
        17
    wangheng486  
    OP
       1 月 26 日
    @unneeded 感谢,我想想怎么弄
    xy19009188
        18
    xy19009188  
       1 月 26 日
    @wangheng486 老哥是真速度,这下我的小 256 有救了
    xy19009188
        19
    xy19009188  
       1 月 26 日
    发现没有 adobe 家的应用
    runking
        20
    runking  
       1 月 26 日
    我之前让 AI 写的这个


    #!/bin/bash
    # =============================================================================
    # 一键恢复脚本 - SSD 数据软链接设置
    # One-Click Restore Script for SSD Data Symlinks
    # =============================================================================
    # 使用方法 / Usage:
    # chmod +x /Volumes/SSD/AppData/restore_symlinks.sh
    # /Volumes/SSD/AppData/restore_symlinks.sh
    # =============================================================================

    set -e

    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    BLUE='\033[0;34m'
    NC='\033[0m'

    SSD_PATH="/Volumes/SSD/AppData"

    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE} SSD 数据软链接恢复脚本${NC}"
    echo -e "${BLUE} 版本: 1.0 | 日期: 2026-01-05${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""

    if [ ! -d "$SSD_PATH" ]; then
    echo -e "${RED}错误: SSD 未挂载: $SSD_PATH${NC}"
    exit 1
    fi

    echo -e "${GREEN} SSD 已检测到${NC}"
    echo ""

    create_symlink() {
    local source="$1"
    local target="$2"
    local name="$3"

    if [ ! -e "$source" ]; then
    echo -e "${YELLOW} 跳过 $name: 数据不存在${NC}"
    return
    fi

    if [ -e "$target" ] && [ ! -L "$target" ]; then
    echo -e "${YELLOW} $name: 目标已存在,跳过${NC}"
    return
    fi

    [ -L "$target" ] && rm "$target"
    mkdir -p "$(dirname "$target")"
    ln -s "$source" "$target"
    echo -e "${GREEN} $name${NC}"
    }

    echo -e "${BLUE}[1/6] Gemini${NC}"
    create_symlink "$SSD_PATH/Gemini/antigravity" "$HOME/.gemini/antigravity" "Gemini Playground"
    create_symlink "$SSD_PATH/Gemini/antigravity-browser-profile" "$HOME/.gemini/antigravity-browser-profile" "Browser Profile"

    echo -e "${BLUE}[2/6] Microsoft Edge${NC}"
    create_symlink "$SSD_PATH/MicrosoftEdge/Microsoft Edge" "$HOME/Library/Caches/Microsoft Edge" "Edge Cache"

    echo -e "${BLUE}[3/6] Xcode${NC}"
    mkdir -p "$HOME/Library/Develper/Xcode"
    create_symlink "$SSD_PATH/Xcode/DerivedData" "$HOME/Library/Developer/Xcode/DerivedData" "DerivedData"

    echo -e "${BLUE}[4/6] Quark${NC}"
    create_symlink "$SSD_PATH/Quark/Data" "$HOME/Library/Application Support/Quark" "Quark"

    echo -e "${BLUE}[5/6] PixPin${NC}"
    create_symlink "$SSD_PATH/PixPin/Data" "$HOME/Library/Application Support/PixPin" "PixPin"

    # New additions based on the provided instruction
    echo -e "${BLUE}[6/6] Google${NC}"
    create_symlink "$SSD_PATH/Google/Data" "$HOME/Library/Application Support/Google" "Google Data"

    echo -e "${BLUE}[7/6] Microsoft Edge App Support${NC}"
    create_symlink "$SSD_PATH/MicrosoftEdge/AppSupport/Data" "$HOME/Library/Application Support/Microsoft Edge" "Edge App Support Data"

    echo -e "${BLUE}[8/6] Apple Wallpaper${NC}"
    create_symlink "$SSD_PATH/AppleWallpaper/Data" "$HOME/Library/Application Support/com.apple.wallpaper" "Apple Wallpaper Data"

    echo -e "${BLUE}[9/6] UE DDC 环境变量${NC}"
    ZSHRC="$HOME/.zshrc"
    if grep -q "UE_LocalDataCachePath" "$ZSHRC" 2>/dev/null; then
    echo -e "${GREEN} 环境变量已存在${NC}"
    else
    echo "" >> "$ZSHRC"
    echo "# Unreal Engine DDC" >> "$ZSHRC"
    echo "export UE_LocalDataCachePath=\"$SSD_PATH/UnrealEngine/DDC\"" >> "$ZSHRC"
    echo "export UE_SharedDataCachePath=\"$SSD_PATH/UnrealEngine/DDC\"" >> "$ZSHRC"
    echo -e "${GREEN} 环境变量已添加${NC}"
    fi

    echo ""
    echo -e "${GREEN} 恢复完成! 请运行: source ~/.zshrc${NC}"
    wangheng486
        21
    wangheng486  
    OP
       1 月 26 日
    这种也不错很清爽
    wangheng486
        22
    wangheng486  
    OP
       1 月 26 日
    @xy19009188 adobe 比较特殊,我是先把/Applications 里的 adobe 文件夹拖到外部存储,然后把外部存储位置修改成 adobe 的文件夹内,这样移动
    GodIsJasonBourne
        23
    GodIsJasonBourne  
       1 月 27 日
    楼主可以!也帮了我 256 的大忙!夸一句,楼主人才!
    wangheng486
        24
    wangheng486  
    OP
       1 月 27 日
    @GodIsJasonBourne 感谢感谢
    wangheng486
        25
    wangheng486  
    OP
       2 月 11 日
    @xy19009188 刚发了新版本,目前支持迁移 adobe 相关应用啦
    关于/a>     帮助文档     自助推广系统     博客     API     FAQ     Solana     3007 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 76ms UTC 02:44 PVG 10:44 LAX 19:44 JFK 22:44
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86