如何将 Homebrew 安装迁移到新位置? [已关闭]

问题描述 投票:0回答:4

我在 $HOME/brew 中安装了

Homebrew
,并且从历史上看它运行良好。不幸的是,随着时间的推移,Homebrew 对
/usr/local
之外的安装的容忍度越来越低。各种公式对安装前缀做出了严格的假设,并且对于非标准前缀无法正常工作(即未经测试)。
brew doctor
命令甚至现在对此发出警告:

Warning: Your Homebrew is not installed to /usr/local
You can install Homebrew anywhere you want, but some brews may only build
correctly if you install in /usr/local. Sorry!

因此,我现在想将我的 Homebrew 安装迁移到

/usr/local
。但是,我不愿意简单地
mv
所有文件,因为我怀疑这会导致问题。我在 Homebrew 网站或此处找不到任何有关将现有安装迁移到新前缀的说明。当然,我可以卸载 Homebrew 然后重新安装它,但我不想重建我所有的小桶。

因此:我如何编写脚本来执行此类迁移?

或者由于链接二进制文件中的硬编码绝对路径,这是不可能的吗?

homebrew
4个回答
62
投票

执行此操作的现代方法是使用 homebrew-bundle

brew tap Homebrew/bundle
brew bundle dump # Creates 'Brewfile' in the current directory
# later ...
brew bundle # Installs packages listed in 'Brewfile'

19
投票

我刚刚编写了一个脚本来实现将自制程序包迁移到新系统的目标,这也适用于您的案例(名为

backup-homebrew.sh
):

#!/bin/bash

echo '#!/bin/bash'
echo ''
echo 'failed_items=""'
echo 'function install_package() {'
echo 'echo EXECUTING: brew install $1 $2'
echo 'brew install $1 $2'
echo '[ $? -ne 0 ] && $failed_items="$failed_items $1"  # package failed to install.'
echo '}'

brew tap | while read tap; do echo "brew tap $tap"; done

brew list --formula | while read item;
do
  echo "install_package $item '$(brew info $item | /usr/bin/grep 'Built from source with:' | /usr/bin/sed 's/^[ \t]*Built from source with:/ /g; s/\,/ /g')'"
done

echo '[ ! -z $failed_items ] && echo The following items were failed to install: && echo $failed_items'

您应该首先在原始系统上运行此脚本以生成恢复脚本:

./backup-homebrew.sh >restore-homebrew.sh && chmod +x restore-homebrew.sh

然后,在新系统(在您的情况下是同一系统)上安装 Homebrew 后,只需运行

restore-homebrew.sh
即可安装原始系统上的所有软件包。

此脚本相对于 @ctrueden 给出的脚本的好处是,此脚本还会尝试备份您在安装软件包时使用的安装选项。

更详细的描述在我的博客


2
投票

正如 Peter Eisentraut 建议的那样,我确实最终通过重新安装来迁移我的 Homebrew 安装。您可以编写一些脚本来重新打开所有额外的水龙头,并重新安装所有以前安装的小桶,而无需太多的手动工作:

#!/bin/sh # save list of kegs for later reinstallation brew list > kegs.txt # back up old Homebrew installation mv $HOME/brew $HOME/old-brew # install Homebrew into /usr/local ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)" # retap all the taps # NB: It is not enough to move the tap repos to their new location, # because Homebrew will not automatically recognize the new formulae. # There might be a configuration file we could edit, but rather than # risk an incomplete data structure, let's just retap everything. for tapDir in $HOME/old-brew/Library/Taps/* do ( cd $tapDir tap=$(git remote -v | \ grep '(fetch)' | \ sed 's/.*github.com\///' | \ sed 's/ (fetch)//') /usr/local/bin/brew tap $tap ) done # reinstall all the kegs /usr/local/bin/brew install $(cat kegs.txt) # much later... ;-) rm -rf kegs.txt $HOME/old-brew
当然,定制的 Homebrew 安装会有额外的问题。例如,如果您对任何与 Homebrew 相关的 Git 存储库提交了更改,您可能需要在重新安装小桶或销毁旧安装之前导入该工作:

cd /usr/local for f in $(find . -name '.git') do ( repoDir=$(dirname $f) cd $f/.. git remote add old-brew-$f $(dirname $HOME/old-brew/$f/..) git fetch old-brew-$f ) done
请注意,我只是非常简单地测试了上面的第二个片段,因为我个人没有以这种方式定制我的 Homebrew。

此方法未解决的 Homebrew 的另一个方面是原始安装期间使用的自定义标志。例如,要安装

wine

,您需要使用 
--universal
 标志安装各种依赖项,并且上面的脚本不会在启用此类标志的情况下重新安装它们。请参阅@xuhdev 的答案以获取这样做的解决方案。


0
投票
或者由于链接二进制文件中的硬编码绝对路径,这是不可能的吗?

确实如此。 您需要从头开始重新安装所有内容。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.