【问题标题】:How do you migrate a Homebrew installation to a new location?如何将 Homebrew 安装迁移到新位置?
【发布时间】:2013-08-26 16:51:58
【问题描述】:

我在$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 然后重新安装它,但我不想重建我所有的小桶。

是否有执行此类迁移的现有脚本或记录实践?

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

【问题讨论】:

    标签: homebrew


    【解决方案1】:

    现代方法是使用homebrew-bundle

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

    【讨论】:

    • @AdamMatan 很高兴看到现在存在内置解决方案。我更改了接受的答案。
    • $ brew bundle dump 错误:您的 Homebrew 已过时。请运行brew update$ brew update 已经是最新的了。 $ brew bundle dump 错误:您的 Homebrew 已过时。请运行brew update$ -1
    【解决方案2】:

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

    更详细的描述在my blog

    【讨论】:

    • 好主意!特别是,它使用相同的选项重新安装这一事实至关重要,因为根据我的经验,复杂的 Homebrew 安装总是有一些带有一些标志或其他的包。
    • 由于这个答案在技术上比我的更优秀而且更通用,所以我现在已经接受了这个答案。 (不过,向读者告诫:我没有亲自测试脚本,因为我个人的 Homebrew 问题已经结束了。)
    • @ctrueden 谢谢!不用担心,我自己测试过了。
    • OSX 10.9.4 迁移助手复制了我的自制软件安装,包括所有软件包。
    • 这很棒。我还使用了Homebrew Cask 并注意到这些包没有在还原文件中被拾取,所以我added a few lines to the script 来处理这些木桶。
    【解决方案3】:

    作为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
    

    请注意,我只是非常轻松地测试了上面的第二个 sn-p,因为我个人没有以这种方式定制我的 Homebrew。

    此方法未解决的 Homebrew 的另一个方面是在原始安装期间使用的自定义标志。例如,要安装wine,您需要使用--universal 标志安装各种依赖项,并且上面的脚本不会在启用此类标志的情况下重新安装它们。请参阅@xuhdev 的答案以了解这样做的解决方案。

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

      • 谢谢彼得,这是有道理的。我赞成你的回答。但是我也写了一个答案,其中包含有关如何减轻重新安装痛苦的更多详细信息,希望对其他人有用,因此我接受了那个答案。
      猜你喜欢
      • 2022-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-15
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多