homebrew 安装 formula 的不同历史版本——以安装 node 为例
homebrew 安装 formula 的不同历史版本——以安装 node 为例
系统环境
- macOS Mojave 10.14
- Homebrew 1.8.0
Homebrew/homebrew-core (git revision 586b0f; last commit 2018-10-27)
Homebrew/homebrew-cask (git revision 76ddc; last commit 2018-10-27)
背景
最近 nodejs 发布了 11.0.0 版本,而我是用 brew 安装了名为 node 的这个 formula ,现在 brew upgrade 会自动将 node 更新到最新版本,于是我遇到了一些问题:
- 一些需要编译安装的依赖包还不支持 node@11 ;
- 不知道如何自动切换两个 formula ( node 和 node@10 )之间的可执行文件;
- 是否能够设定某个 formula 不自动更新?
在经过一番折腾后,现在我删掉了 node 和 node@10 两个 formula ,包括之前安装的历史版本(所以算是多走了一点弯路),想要同时保留 10 和 11 两个大版本,并可方便切换。
前置条件
若下列条件不满足,可能导致需要额外的操作来解决环境问题,这些操作不在本文讨论范围内:
- 只通过 homebrew 来安装 node ;
- 没有使用如 n / nvm 等 node 版本管理工具;
- 某种意义下连接性良好的网络。
适用情况
本文覆盖了如下四种情况:
- 某个 formula 跟随着更新上来,没有运行过 cleanup 或 force uninstall ,想切回旧版本的(见关键点三);
- 全新安装且只想安装某个 formula (如 node 而非 node@10 ),但又想先用着旧版本的(见解决方案一);
- 某个 formula 在用的是旧版本,但想切换编译选项(如
--with-openssl@1.1)重新安装(同上); - 在两个 formula 之间切换,如一个是 LTS 版的,一个是不稳定版的(见解决方案二)。
关键点
如何在 brew install / upgrade 时禁止自动更新
这一步很关键,否则我们总是会安装到最新版本。只要在运行命令前,设置环境变量 HOMEBREW_NO_AUTO_UPDATE 为 1 就可以了,比如:
$ HOMEBREW_NO_AUTO_UPDATE=1 brew install node
也可以直接写进 shell 配置文件中(如 .bashrc / .zshrc 等):
export HOMEBREW_NO_AUTO_UPDATE=1
查看某个 formula 的本地已安装版本
有两种方式可查看,一是 brew list --versions ,输出以空格分隔,简洁明了,推荐使用:
$ brew list node --versions
node 11.0.0 10.12.0
$ brew list zsh --versions |tr ' ' '\n'
node
11.0.0
10.12.0
二是 brew info 在查看 formula 信息时也可看到本地已安装的版本:
$ brew info node
$ brew info node |grep -i '\/cellar'
/usr/local/Cellar/node/10.12.0 (3,668 files, 41.7MB)
/usr/local/Cellar/node/11.0.0 (3,665 files, 42MB) *
后面带有的星号 * 表示当前激活的版本。
切换某个 formula 的版本
自有的 brew switch 命令即可,之前感觉 brew 较易上手,安装后没看文档直接用到现在,所以不知道这个命令。命令的说明也很直观:
brew switch formula version:
Symlink all of the specific version of formula's install to Homebrew prefix.
直接键盘一顿敲就行了,如 brew switch node 10.12.0 。
解决方案
安装某个 formula 的历史版本
切换到 brew 的仓库目录下
$ cd "$(brew --repo homebrew/core)"
查看某个 formula 的 git 历史记录
$ git log master -- Formula/node.rb
在里面找到想要的历史版本,比如这个就挺像我所需要的:
commit b801cc6b71e7c09448b4f823e493710665de68eb
Author: BrewTestBot <homebrew-test-bot@lists.sfconservancy.org>
Date: Thu Oct 11 00:12:43 2018 +0000 node: update 10.12.0 bottle.
检出 git 历史提交
$ git checkout b801cc6b71e7c09448b4f823e493710665de68eb
在禁止自动更新的前提下安装这个 formula
$ HOMEBREW_NO_AUTO_UPDATE=1 brew install node --with-openssl@1.1
由于刚才第 3 步后处于分离头指针状态下,记得要切回来
$ git checkout master
升级这个 formula 试试
$ brew upgrade node
检查当前版本,应该是最新的,现在再把它切回来
$ node -v
v11.0.0
$ brew switch node 10.12.0
Cleaning /usr/local/Cellar/node/10.12.0
Cleaning /usr/local/Cellar/node/11.0.0
7 links created for /usr/local/Cellar/node/10.12.0
$ node -v
v10.12.0
在两个 formula 之间切换
我们也可以在 node 和 node@10 两个 formula 之间切换文件链接。但是注意,这种方法可能会在运行 brew doctor 时产生警告,因为可能会有一个不是 keg-only 的包没有被链接到 Cellar 中(如为了使用 node@10 而解除了 node 的链接),这个警告可以不去理会,但必须记住我们做过这样的操作。
假定已经安装了 node ,现在安装 node@10 ,键盘一顿乱敲
$ brew install node@10
通常像这样名字后面带有版本号的 formula 都是 keg-only 的,简单来说就是 brew 不会自动帮我们链接文件
先解除 node 的文件链接
$ brew unlink node
链接 node@10 的文件
$ brew link node@10
这时会提示这个包是 keg-only 的,需要加上
--force选项。如果第 2 步没有进行,还会提示你需要先解除 node 的链接,或者直接用--overwrite选项覆盖原有的链接。由于 npm 目录一定需要覆盖,所以我们总是可以打开--overwrite选项:$ brew link node@10 --force --overwrite
检查当前版本,在解决方案一中提到过了,方法也有很多种,此处略过。
后续问题
全局安装的包支持的 node 版本可能不同
是的,这个问题一定会存在,建议通过切换 npm prefix 路径解决,把不同版本 node 下安装的全局包隔离开来。当然 nvm 等方案也可以解决问题,但本文是不一样的烟火。$ mkdir -p ~/.npm-node10/npm-global
$ npm config set prefix ~/.npm-node10/npm-global
$ export PATH="$HOME/.npm-node10/npm-global/bin:$PATH"
手动切换确实比较繁琐,可以写个 shell 脚本把切换 formula 和切换 npm prefix 结合起来。
如何固定某个 formula 的版本?
虽然说不运行brew upgrade就一直是固定的版本,但如果想只固定某个 formula 的版本而允许其他可以升级,也是极好的。自带的 pin 、 unpin 命令就是用来解决这一问题,如:brew pin node。如何删除某个 formula 的旧版本?
尽管brew cleanup可以删除一个 formula 的所有旧版本,但通常我们可能只想删除某几个太旧且多余的版本而不是全部。 brew 没有提供这样的命令,我们可以直接从 Cellar 里面删除:$ brew info node |grep -i '\/cellar'
/usr/local/Cellar/node/10.12.0 (3,668 files, 41.7MB)
/usr/local/Cellar/node/11.0.0 (3,665 files, 42MB) *
$ rm -rf /usr/local/Cellar/node/10.12.0
初步测试未发现有副作用,欢迎讨论和建议。
如何在升级时自动删除旧版本?
根据brew upgrade命令的说明,设置一个 HOMEBREW_UPGRADE_CLEANUP 环境变量就好了,比较简单。
参考资料
- Tips and Tricks - Homebrew Documentation
- Homebrew terminology - Homebrew Documentation
- FAQ - Homebrew Documentation
- homebrew - how to install older versions - Stack Overflow
- Homebrew install specific version of formula? - Stack Overflow
- Using Homebrew how do I remove some specific versions but not all old versions - Stack Overflow
本文基于
知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 发布,欢迎引用、转载或演绎,但是必须保留本文的署名 BlackStorm 以及本文链接 http://www.cnblogs.com/BlackStorm/p/homebrew-install-old-versions-take-node-for-example.html ,且未经许可不能用于商业目的。如有疑问或授权协商请与我联系。
homebrew 安装 formula 的不同历史版本——以安装 node 为例的更多相关文章
- anaconda 下多版本Python 安装说明
网上针对多版本的Python兼容安装的文章逐渐增多,都是大家在实践中总结的经验.本人的安装经过几次的反复实验还是觉得其中一种更为方便. 有人的安装方法是: 1. 先安装一个版本的python(一般先安 ...
- ubuntu下不同版本python安装pip及pip的使用
由于ubuntu系统自带python2.7(默认)和python3.4,所以不需要自己安装python. 可以使用python -V和python3 -V查看已安装python版本. 在不同版本的py ...
- 通过 PECL 安装 PHP 扩展(以 CentOS7 中安装 swoole 为例)
原文地址:https://blog.csdn.net/kikajack/article/details/82495190 常用工具PECL 和 phpize官网文档 PHP 有大量的扩展可以使用,比如 ...
- TortoiseSVN历史版本安装及svn服务器搭建
一.TortoiseSVN安装 1.TortoiseSVN下载 网址如下:https://tortoisesvn.net/downloads.html 进入客户端下载页面,根据你的电脑选择是64位 ...
- SVN 安装配置详解,包含服务器和客户端,外带一个项目演示,提交,更改,下载历史版本,撤销
本次要介绍的是svn版本管理工具包含2个: 服务器端:visualsvn server 下载地址为:https://www.visualsvn.com/server/download/ 此处演示的 ...
- 下载历史版本App超详细教程
有些时候我们需要下载旧版本的 App 进行研究或者其他用途,然而在 iOS 下,苹果的 App Store 里面默认只能下载最新版本的 App,对滴,就是这么任性,不服不行.然而在 Android 里 ...
- homebrew & brew cask使用技巧及Mac软件安装
homebrew 安装 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/m ...
- 如何在Oracle官网下载历史版本JDK
打开Oracle官网,准备下载java JDK(下载时需要使用注册用户登陆,可以免费注册) 官网地址:http://www.oracle.com/ 2 鼠标悬停Downloads,会出现相关内容,如下 ...
- 在Centos环境下安装兼容Apache2.4高版本SVN服务
在阿里云Centos环境下,搭建PHP运行环境,PHP选择了php7版本,Mysql选择了5.7版本,Apache选择了2.4版本,在搭建SVN版本控制服务过程中出现了不兼容问题,当前环境下Apach ...
随机推荐
- 用react+redux写一个todo
概述 最近学习redux,打算用redux写了一个todo.记录下来,供以后开发时参考,相信对其他人也有用. 代码 代码请见我的github 组织架构如下图:
- CUDA driver version is insufficient for CUDA runtime version 解决
配置ubuntu17.1+CUDA9.2的caffe环境,CUDA sample编译完成,执行到./deviceQuery时报错:CUDA driver version is insufficient ...
- 记hangfire后台任务运行一段时间后不运行了。
什么是Hangfire Hangfire 是一个开源的.NET任务调度框架,目前1.6+版本已支持.NET Core.个人认为它最大特点在于内置提供集成化的控制台,方便后台查看及监控. https:/ ...
- 根据PDF模板生成PDF文件(基于iTextSharp)
根据PDF模板生成PDF文件,这里主要借助iTextSharp工具来完成.场景是这样的,假如要做一个电子协议,用过通过在线填写表单数据,然后系统根据用户填写的数据,生成电子档的协议.原理很简单,但是每 ...
- 7z 程序打包 Demo
最近准备做一个用户端 异常收集的程序 需要收集用户机器的程序日志和相关信息 准备打包发回来 所以研究了一下7Z 文件压缩 做一个笔记吧 遇到的问题: 1:VS2008 遇到 loadlibrary ...
- 前端进击的巨人(五):学会函数柯里化(curry)
柯里化(Curring, 以逻辑学家Haskell Curry命名) 写在开头 柯里化理解的基础来源于我们前几篇文章构建的知识,如果还未能掌握闭包,建议回阅前文. 代码例子会用到 apply/call ...
- Spring Boot + Spring Cloud 构建微服务系统(十):配置中心(Spring Cloud Bus)
技术背景 我们在上一篇讲到,Spring Boot程序只在启动的时候加载配置文件信息,这样在GIT仓库配置修改之后,虽然配置中心服务器能够读取最新的提交信息,但是配置中心客户端却不会重新读取,以至于不 ...
- epoll的ET和LT模式
epoll有两种模式,Edge Triggered(简称ET) 和 Level Triggered(简称LT). 在采用这两种模式时要注意的是,如果采用ET模式,那么仅当状态发生变化时才会通知,而采用 ...
- 通过反编译深入理解Java String及intern
一.字符串问题 字符串在我们平时的编码工作中其实用的非常多,并且用起来也比较简单,所以很少有人对其做特别深入的研究.倒是面试或者笔试的时候,往往会涉及比较深入和难度大一点的问题.我在招聘的时候也偶尔会 ...
- nginx介绍(六) - 通过反向代理实现跨域访问
前言 跨域访问问题, 相信很多人都遇到过, 并且都用不同的办法去解决过. 方法有很多种, 不一一叙述了. 这里主要使用nginx反向代理来解决跨域问题. 啥是跨域 假如你是百度开发人员, 在百度页面去 ...
知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议