Homebrew是MacOSX上的软件包管理工具, 可以方便安装各种Apple没有预装的东西。安装软件时, 还会自动安装依赖, 但是卸载时, 依赖不会被卸载。(本人有洁癖, 喜欢把没用的东西都清理掉)
获取安装列表
Homebrew有提供命令
brew deps --installed
然后会出现一堆软件及其依赖, 例如:
autoconf:
automake: autoconf
carthage:
cmake:
python@2: gdbm openssl readline sqlite
readline:
sqlite: readline
tree:
usbmuxd: libplist libusb
watchman: gdbm openssl pcre python@2 readline sqlite
...
数量少的话, 人工分析也是可以的, 然而平时乱装东西(安装是在方便)...
分析(python3)
执行命令, 获取依赖列表
# 代码均为片段, 完整代码请到下面的源码地址 with os.popen('brew deps --installed') as popen: dep_lines = popen.read().split('\n')
解析列表
# 代码均为片段, 完整代码请到下面的源码地址 class BrewPackage: def __init__(self, name: str): self.name = name self.deps = [] self.is_dep = False def __repr__(self) -> str: return '{}: {}'.format(self.name, self.deps) for line in dep_lines: if not line: continue result = line.split(': ') name = result[0] deps_name = result[1].split(' ') if len(result) == 2 and result[1] else None package = BrewPackage(name) if not deps_name: continue for dep_name in deps_name: dep_package = BrewPackage(name) dep_package.id_dep = True package.deps.append(dep_package)
数据整理
# 代码均为片段, 完整代码请到下面的源码地址 # 上面第二步, 把BrewPackage缓存起来(每一个name只存在一个BrewPackage), 然后数据就会变成一张单向图结构. all_package_dict = {} # name -> package def get_cache_package(package_name: str) -> BrewPackage: pkg = all_package_dict.get(package_name) if not pkg: pkg = BrewPackage(package_name) all_package_dict[package_name] = pkg return pkg # 把第二部创建BrewPackage的部分, 换成get_cache_package即可
输出结果
# 代码均为片段, 完整代码请到下面的源码地址 # 为了更好看的输出结果, BrewPackage重写__repr__方法 @classmethod def _deps_str(cls, package, level: int = 0, need_deep: bool = True): ts = '\t' * (level + 1) s = '' for p in package.deps: s += '{}- {}\n'.format(ts, p.name) if need_deep and p.deps: s += cls._deps_str(p, level + 1) return s def __repr__(self): return '{}:\n{}'.format(self.name, BrewPackage._deps_str(self)) ------------------------------------------------------------------------- # 输出所有软件包 print('All package and deps') print('--------------------') for package in all_package_dict: print(package) print('\n') # 这里print出来的包, 都没有被依赖, 看看那个不认识或不想要都可以卸载掉, 卸载完一遍后, 需要再次运行该程序分析 # 如此循环, 直到没有找到需要卸载的包, 这样就清理干净了 print('Not dependent packages') print('----------------------') not_dep_package = [p for p in all_package_dict.values() if not p.is_dep] for p in not_dep_package: print(p.name)
完整地址: