mac 删除pkg包

mac osx上大多数应用程序都是通过.DMG或者.pkg来安装的(当然brew方式安装的除外)。

如果是通过DMG方式安装的软件,要删除它就挺简单,直接从osx的应用程序文件夹上删除即可。

那么pkg方式安装的软件又该怎么删除呢?

mac并没有提供什么快捷删除方式,我们只能找到pkg安装后产生的文件,然后删除它。

方式一

mac会维护一份pkg安装历史,只要找到那个文件夹,我们就可以对症下药了。

我的机子是osx 10.8.4,pkg历史安装列表在/private/var/db/receipts目录下:

cd /private/var/db/receipts
ls -l

列出该目录,可以看到类似如下内容:

-rw-r--r--    1 root  wheel     47315  6 15 15:48 com.codeius.izip.bom
-rw-r--r--    1 root  wheel       253  6 15 15:48 com.codeius.izip.plist

找到.bom文件后,我们就可以使用以下命令找到安装的文件列表:

lsbom -pf com.codeius.izip.bom

执行上述命令后,输出了类似以下内容:

/iZip.app
./iZip.app/Contents
./iZip.app/Contents/CodeResources
./iZip.app/Contents/Frameworks
./iZip.app/Contents/Frameworks/libarchive.2.dylib
./iZip.app/Contents/Frameworks/libcurl.framework
./iZip.app/Contents/Frameworks/libcurl.framework/Headers
./iZip.app/Contents/Frameworks/libcurl.framework/Resources
./iZip.app/Contents/Frameworks/libcurl.framework/Versions
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/CodeResources
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curl.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curlbuild.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curlbuild32.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curlbuild64.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curlrules.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curlver.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/easy.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/mprintf.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/multi.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/stdcheaders.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/typecheck-gcc.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/types.h
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Resources
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Resources/Info.plist
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/_CodeSignature
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/_CodeSignature/CodeResources
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/libcurl
./iZip.app/Contents/Frameworks/libcurl.framework/Versions/Current
./iZip.app/Contents/Frameworks/libcurl.framework/libcurl
./iZip.app/Contents/Info.plist
./iZip.app/Contents/MacOS
./iZip.app/Contents/MacOS/iZip
./iZip.app/Contents/PkgInfo
./iZip.app/Contents/Resources
...

以上找到的这些文件,就是安装pkg的时候产生的文件,这些文件删除了应该就ok了!

方式二

方式一虽然可行,但是很多人都抱怨没找到pkg安装历史列表目录(确实不同版本的系统,目录是不一样的),那有没有更自动一点的呢?

pkgutil命令这个时候就派上用场了。查看一下帮助:

man pkgutil # 或者直接pkgutil

看看有啥功能我们能用的:

Receipt Database Commands:
  --pkgs, --packages     List all currently installed package IDs on --volume
  --pkgs-plist           List all package IDs on --volume in plist format
  ...
  --files PKGID          List files installed by the specified package
  ...

我们先找一下我们要删除的pkg包名(以上述iZip为例):

pkgutil --pkgs | grep -i izip

看一下输出了啥:

com.codeius.izip

ok,现在就可以找出izip pkg到底装了哪些文件:

pkgutil --file com.codeius.izip

终端输出的结果:

iZip.app
iZip.app/Contents
iZip.app/Contents/CodeResources
iZip.app/Contents/Frameworks
iZip.app/Contents/Frameworks/libarchive.2.dylib
iZip.app/Contents/Frameworks/libcurl.framework
iZip.app/Contents/Frameworks/libcurl.framework/Headers
iZip.app/Contents/Frameworks/libcurl.framework/Resources
iZip.app/Contents/Frameworks/libcurl.framework/Versions
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/CodeResources
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curl.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curlbuild.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curlbuild32.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curlbuild64.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curlrules.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/curlver.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/easy.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/mprintf.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/multi.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/stdcheaders.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/typecheck-gcc.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Headers/curl/types.h
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Resources
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/Resources/Info.plist
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/_CodeSignature
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/_CodeSignature/CodeResources
iZip.app/Contents/Frameworks/libcurl.framework/Versions/A/libcurl
iZip.app/Contents/Frameworks/libcurl.framework/Versions/Current
iZip.app/Contents/Frameworks/libcurl.framework/libcurl
iZip.app/Contents/Info.plist
iZip.app/Contents/MacOS
iZip.app/Contents/MacOS/iZip
iZip.app/Contents/PkgInfo
iZip.app/Contents/Resources
...

把这些文件删了应该就算卸载完毕。(risk on your own!)

方式三

哈哈,有的人要讲究效率,不喜欢折腾半天,就会问能不能一键搞定啊?

真别说,还真有http://www.corecode.at/uninstallpkg/,偶然发现这个东西,貌似不错,试用了一下,好像真成功卸载了。(就是不知道有没有卸载干净...)

<think>我们正在讨论Mac上的PKG安装增量更新方法。增量更新通常用于减少用户需要下载的文件大小,只下载变更部分(delta)而非整个新安装。这可以通过比较旧版和新版PKG文件的差异,生成一个补丁文件(patch),用户下载这个补丁文件并应用到旧版PKG上即可得到新版PKG。在Mac系统中,PKG文件实际上是目录结构(在Finder中显示为单一文件,实际是含特定内容的目录)。我们可以使用`xar`工具来解和重新打PKG文件。增量更新的核心在于如何生成两个版本PKG之间的差异(delta)以及如何应用这个差异。一种常见的方法是使用二进制差分工具,如`bsdiff`和`bspatch`(开源工具)。`bsdiff`可以计算两个二进制文件之间的差异,生成一个补丁文件,而`bspatch`则可以将补丁应用到旧文件上生成新文件。步骤大致如下:1.解旧版PKG和新版PKG,得到其内部文件结构。2.对于每个需要更新的文件(特别是大文件),使用`bsdiff`生成补丁。3.将补丁文件以及新增的文件打成一个增量更新(通常也是一个PKG格式)。4.在更新时,先解旧版PKG,然后应用补丁(使用`bspatch`)和替换或添加新文件,最后重新打成新版PKG。但是,需要注意的是,PKG文件可能含脚本、资源文件以及签名信息。在增量更新过程中,签名会失效,因此需要在更新后重新签名。另外,如果PKG文件中的文件结构发生变化(如文件删除或重命名),则需要在补丁含相应的操作指令。由于PKG文件是目录,我们也可以将其视为一个文件(在终端中,PKG文件实际上是扩展名为.pkg的目录,但通常我们将其视为一个单一文件进行差分)。但更精细的做法是解后对内部文件进行差分。实际应用中,苹果官方提供了软件更新机制(通过AppStore),但如果你需要自己实现增量更新,可以参考以下步骤:###生成增量更新(补丁)的步骤:1.准备旧版本PKG和新版本PKG。2.使用`xar`解两个PKG文件:```bashxar-xfold.pkg-Cold_pkgxar-xfnew.pkg-Cnew_pkg```3.进入解后的目录,比较两个目录中的文件。对于每个文件,如果旧版本中存在且新版本中也有,则使用`bsdiff`生成补丁:```bashbsdiffold_pkg/filenew_pkg/filefile.patch```4.将生成的补丁文件、新增的文件以及一个更新脚本(用于指导如何应用补丁和添加/删除文件)打到一个新的PKG文件中。这个更新脚本应该含以下步骤:-解压原始PKG(如果用户安装的是旧版,则系统中可能有旧版文件,但这里我们考虑更新安装本身,所以可能需要先找到旧版安装的位置,这通常由应用程序自己管理)-应用补丁:使用`bspatch`对旧文件打补丁-删除已移除的文件-添加新文件5.重新打PKG,并使用`productsign`签名(如果需要)。###应用增量更新的步骤:1.用户下载增量更新(例如update.pkg)。2.运行更新,更新中的脚本会执行以下操作:-定位旧版安装(或已安装的文件)-应用补丁,更新文件-完成更新但是,需要注意的是,这种方法通常用于更新已安装的应用程序文件,而不是更新安装本身。因为用户可能已经安装了应用程序,我们只需要更新应用程序的文件,而不需要重新运行整个安装过程。因此,更常见的做法是更新应用程序的安装目录(例如`/Applications/AppName.app`)中的文件。这时,增量更新实际上是一个只含变更部分的PKG安装,在安装时,它会将补丁应用到已安装的文件上,或者直接替换变更的文件。###使用工具苹果提供了`SoftwareUpdate`框架,但如果你需要自己实现,可以使用`bsdiff`/`bspatch`工具链。在Mac上,你可以通过Homebrew安装`bsdiff`:```bashbrewinstallbsdiff```###注意事项1.**签名**:对PKG文件进行修改后,必须重新签名,否则系统可能会拒绝安装。你可以使用`productsign`工具进行签名:```bashproductsign--sign"DeveloperIDInstaller:YourName(YourID)"unsigned.pkgsigned.pkg```2.**文件权限**:在解和重新打过程中,注意保持文件权限和属性不变。###示例脚本(生成补丁)以下是一个简化的生成增量更新的脚本示例(假设我们有两个版本的应用程序目录,分别是`OldApp.app`和`NewApp.app`,我们要生成一个增量更新):```bash#!/bin/bash#生成补丁文件bsdiffOldApp.app/Contents/MacOS/OldAppNewApp.app/Contents/MacOS/OldAppbinary.patch#创建更新目录结构mkdir-pUpdatePackage/PayloadcpNewApp.app/Contents/Info.plistUpdatePackage/Payload/#假设只有可执行文件改变,其他文件不变,所以只含补丁和更新脚本cpbinary.patchUpdatePackage/Payload/#创建更新脚本(postinstall)cat>UpdatePackage/scripts/postinstall<<EOF#!/bin/bash#定位到应用程序目录APP_PATH="/Applications/OldApp.app"#应用补丁bspatch"$APP_PATH/Contents/MacOS/OldApp""$APP_PATH/Contents/MacOS/OldApp_new""Payload/binary.patch"mv"$APP_PATH/Contents/MacOS/OldApp_new""$APP_PATH/Contents/MacOS/OldApp"chmod+x"$APP_PATH/Contents/MacOS/OldApp"EOFchmod+xUpdatePackage/scripts/postinstall#构建PKGpkgbuild--rootUpdatePackage/Payload--scriptsUpdatePackage/scripts--identifiercom.example.app.update--version1.0.1Update.pkg#签名productsign--sign"DeveloperIDInstaller:..."Update.pkgSignedUpdate.pkg```这个例子只更新了可执行文件,实际中可能需要更新多个文件。###总结MacPKG文件的增量更新可以通过二进制差分工具(如bsdiff)生成补丁,然后制作一个含补丁和应用补丁脚本的PKG来实现。这个更新在安装时执行脚本,将补丁应用到已安装的文件上。§§相关问题§§1.如何对Mac应用程序(.app)进行增量更新?2.如何对PKG文件进行签名?3.bsdiff和bspatch工具的使用方法有哪些?4.在Mac上,如何创建PKG安装?</think>### Mac PKG 文件增量更新方法 在 macOS 上实现 PKG 安装的增量更新,核心是通过**二进制差分工具**生成新旧版本之间的差异补丁(delta patch),用户只需下载小体积的补丁文件即可完成更新。以下是具体方法: #### 1. **使用 bsdiff/bspatch 工具链** 这是最常用的开源解决方案,专为二进制文件差分设计: ```bash # 安装 bsdiff (通过 Homebrew) brew install bsdiff # 生成差异补丁 (old.pkg → new.pkg → delta.patch) bsdiff old.pkg new.pkg delta.patch # 应用补丁更新 (用户端执行) bspatch old.pkg updated.pkg delta.patch ``` **特点**: - 补丁体积通常比完整小 60-90% - 支持任何二进制格式的 PKG 文件 - 跨平台兼容(macOS/Linux) #### 2. **增量更新制作流程** ```mermaid graph LR A[旧版PKG] --> B(bsdiff生成补丁) C[新版PKG] --> B B --> D[delta.patch] D --> E[打为更新安装程序] E --> F[用户下载补丁] F --> G[bspatch应用更新] ``` #### 3. **签名验证** 更新后的 PKG 需重新签名以确保安全性: ```bash # 使用开发者证书签名 productsign --sign "Developer ID Installer: Your Name (TeamID)" updated.pkg signed.pkg ``` **注意**:签名必须在补丁应用后执行,否则会破坏证书验证[^1]。 #### 4. **自动化脚本示例** 创建含更新逻辑的 postinstall 脚本: ```bash #!/bin/bash # 检查旧版是否存在 if [ ! -f "/Applications/AppName.app/Contents/Info.plist" ]; then echo "未找到旧版本,执行完整安装" /usr/sbin/installer -pkg FullInstaller.pkg -target / exit 0 fi # 应用增量更新 bspatch /Applications/AppName.app/Contents/MacOS/binary \ /Applications/AppName.app/Contents/MacOS/binary_new \ delta.bin # 替换文件 mv /Applications/AppName.app/Contents/MacOS/binary_new \ /Applications/AppName.app/Contents/MacOS/binary ``` #### 5. **优化建议** - **分块差分**:对大型 PKG 按文件拆分处理 ```bash # 解PKG xar -xf old.pkg -C old_pkg xar -xf new.pkg -C new_pkg # 对每个文件生成补丁 find new_pkg -type f -exec bsdiff old_pkg/{} new_pkg/{} {}.patch \; ``` - **压缩补丁**:使用 bzip2 二次压缩 ```bash bzip2 delta.patch # 生成 delta.patch.bz2 ``` - **版本校验**:在脚本中加入版本检查逻辑,防止错误更新 #### 6. **企业级方案** - **Sparkle 框架**:开源更新框架,支持 PKG 增量更新 - **Installomator**:专为 macOS 打设计的工具链 - **苹果官方方案**:通过 App Store 分发时自动处理增量更新 > **重要提示**:增量更新需确保文件定位绝对准确,测试时应覆盖: > 1. 从旧版到新版的更新路径 > 2. 多版本跳跃更新场景 > 3. 更新失败的回滚机制[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值