在过去的 5 年里,我一直使用 linux 作为我执行科学计算的日常操作系统。我最近的工作给了我一台 Mac,我将成为未来几个月的主要用户。我一直在 Mac 上的 Free-BSD bash 环境和我习惯的 GNU 环境之间遇到冲突,无论是我设置的 bash 脚本还是我尝试运行 bash 命令时(coreutils
,findutils
, 等等)。我不想完全切换到 Free-BSD 实用程序,因为我所有的其他计算机以及我们的 HPC 都使用带有 GNU 实用程序的 linux。我想避免必须维护两组 bash 脚本,并且还必须记住两个系统之间不同标志和功能的细微差别。我也不想破坏其他用户将使用的 Mac 的任何 gui 实用程序等(在接下来的几个月内或在将其提供给其他人时)。此外,对此相关问题的回答警告不要将 Mac Free-BSD 实用程序完全替换为 GNU 实用程序。
是否可以安装/设置单独的 bash 环境以仅使用 GNU 实用程序,同时保留系统 Free-BSD 实用程序? 我期望最有希望的选项是将我的$PATH
变量设置为指向一个包含 GNU 可执行文件(带有它们的标准名称)的目录,同时忽略 Free-BSD 的。我如何将其应用于我的跨平台 bash 脚本?是否有值得考虑的替代方案?
首先,这不仅仅是coreutils
. 相当于GNUfindutils
的 BSD也有很大不同,几乎每个与动态链接相关的命令都不同,等等。
然后最重要的是,您必须处理版本差异:OS X 仍然提供许多旧软件以保留在 GPL2 而不是 GPL3,例如 Bash 3.x 而不是 Bash 4.x。该自动工具也经常对于过时出血边缘的Linux发行版。
问题核心部分的答案是,“当然,为什么不呢?” 您可以使用Homebrew安装所有这些替代 GNU 工具,然后将$(brew --prefix coreutils)/libexec/gnubin
和/usr/local/bin
first 放入您的PATH
以确保首先找到它们:
export PATH="$(brew --prefix coreutils)/libexec/gnubin:/usr/local/bin:$PATH"
Run Code Online (Sandbox Code Playgroud)
如果出于某种原因brew
将包安装到另一个位置,也将其包含在PATH
变量中。
如果您只想替换几个包,那么棘手的一点是处理所有名称更改。每当brew
安装已在核心操作系统中实现的程序时,例如在安装 GNU 时coreutils
,它都会对其版本进行不同的命名,以便您可以根据当时的需要运行任一版本。与其重命名所有这些符号链接¹,我建议您使用一个间接层来修复所有这些:
$ mkdir ~/linux
$ cd ~/linux
$ ln -s /usr/local/bin/gmv mv
...etc for all the other tools you want to rename to cover OS versions
$ export PATH=$HOME/linux:$PATH
...try it out...
Run Code Online (Sandbox Code Playgroud)
一旦你高兴与您的新的环境,你可以把export PATH=$HOME/linux:$PATH
到你~/.bash_profile
。
这需要交互式使用,无论是批量替换还是单个应用程序替换。
不幸的是,它并没有完全解决 shell 脚本问题,因为有时 shell 脚本有自己的环境,例如从cron
. 在这种情况下,您可以修改PATH
每个跨平台 shell 脚本顶部的 :
#!/bin/bash
export PATH="$HOME/linux:$(brew --prefix coreutils)/libexec/gnubin:/usr/local/bin:$PATH"
Run Code Online (Sandbox Code Playgroud)
您不需要将其设置为有条件的,因为它只是为 shell 提供了另一个查找程序的位置。
脚注
/usr/local/bin/gmv
→../Cellar/coreutils/$version/bin/gmv
相关文章