如何将Homebrew安装迁移到新位置?

时间:2013-08-26 16:51:58

标签: homebrew

我在$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网站上找不到任何说明,或者在此处将现有安装迁移到新前缀。当然,我可以uninstall Homebrew然后重新安装它,但我不想重建我的所有桶。

是否存在执行此类迁移的现有脚本或文档化实践?

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

4 个答案:

答案 0 :(得分:32)

现代的方法是使用homebrew-bundle

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

答案 1 :(得分:16)

我刚写了一个脚本来实现将自制软件包迁移到新系统的目标,这也适用于您的案例(名为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 | 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提供的脚本的好处是,此脚本还会尝试备份安装软件包时使用的安装选项。

更详细的说明在my blog

答案 2 :(得分:2)

作为suggested by 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的答案,了解解决方案。

答案 3 :(得分:1)

  

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

事实上。您需要从头开始重新安装所有内容。