我有一个Homebrew公式,我希望卸载/删除及其所有依赖项,跳过其他包所依赖的包(在包管理器中称为级联包删除)。

例如,卸载依赖于包b和c的包a,其中包d也依赖于包c。结果应该卸载a和b,跳过c。

我该怎么做呢?

必须有一种方法来卸载一个包而不留下不必要的垃圾。


当前回答

一个更完整的伯恩壳函数

已经有很多好的答案,但有些已经过时了,没有一个是完全完整的。特别是,它们中的大多数会删除依赖项,但仍然让您自行删除最初的目标公式。如果您想一次卸载多个公式,那么所发布的一行程序也可能很乏味。

下面是一个与boure兼容的shell函数(没有任何已知的Bashisms),它接受一个公式列表,删除每个公式的依赖项,删除公式本身的所有副本,然后重新安装任何缺失的依赖项。

unbrew () {
    local formula
    for formula in "$@"; do
        brew deps "$formula" |
        xargs brew uninstall --ignore-dependencies --force
        brew uninstall --force "$formula"
    done
    brew missing | cut -f2 -d: | sort -u | xargs brew install
}

它在Homebrew 1.7.4上进行了测试。

警告

这适用于我测试过的所有标准公式。它目前还不能处理酒桶,但如果你试图解煮一个与标准公式同名的酒桶(例如MacVim),它也不会大声抱怨。

其他回答

@jfmercer的答案必须稍微修改一下才能使用当前的brew,因为缺少brew的输出已经改变:

brew deps [FORMULA] | xargs brew remove --ignore-dependencies && brew missing | cut -f1 -d: | xargs brew install

稍微精致;可提供多个包装;没有供应时有使用。

#!/bin/bash
# Removes the package and all dependancies.

if [ $# -eq 0 ]; then
   echo "$(basename $0) <pkg> [<pkg> [...]]"
   exit 1
fi

function tree() {
    pkg="$1"
    join <(brew leaves) <(sort <(brew deps ${pkg}; echo ${pkg}))
} 

let e=0
for pkg in "$@"; do
    printf "Purging %s and its dependencies...\n" "${pkg}"
    deps=( $(tree ${pkg}) )
    while (( ${#deps[@]} > 0 )); do
        brew rm "${deps[@]}"
        deps=( $(tree ${pkg}) )
    done
done

酿造rmtree根本不能工作。从这个问题的链接中,我发现了rmrec,它实际上是有效的。天知道为什么brew没有这样的原生命令。

brew tap ggpeti/rmrec
brew rmrec pkgname

这里的目标是删除给定的包及其依赖关系,而不破坏另一个包的依赖关系。我使用这个命令:

brew deps [FORMULA] | xargs brew remove --ignore-dependencies && brew missing | xargs brew install

注:经过编辑以反映@alphadogg的有用评论。

其他答案对我来说都不管用,但这个答案(用鱼壳)管用:

brew remove <package>
for p in (brew deps <package>)
    brew remove $p
end

因为当其他包依赖于p时,brew remove $p失败。