4

For the last 5 years, I have used linux as my everyday OS for performing scientific computing. My work recently gave me a Mac that I will be the primary user for the next few months. I keep running into conflicts between the Free-BSD bash environment on the Mac and the GNU environment I am used to, both with bash scripts I have setup and as I try to run bash commands (coreutils, findutils, etc). I do not want to switch completely to the Free-BSD utilies as all my other computers as well as our HPC's use linux with the GNU utilities. I want to avoid having to maintain two sets of bash scripts and also having to remember the nuances of the differing flags and functionalities between the two systems. I also do not want to break any of Mac's gui utilites etc that other users will use (either in the next few months or when it is given to someone else). Additionally, responses to this related question warn against completely replacing the Mac Free-BSD utilities with GNU ones.

Is it possible to install/setup a separate bash environment to use only the GNU utilities while leaving the system Free-BSD ones in place? My expect the most promising option is setting up my $PATH variable to point to a directory containing the GNU executables (with their standard names) while ignoring the Free-BSD ones. How could I apply this to my cross-platform bash scripts? Are there alternative options worth considering?

  • 2
    Your title says your question is about bash, but the question text seems to be about coreutils. OS X has had bash for many years. – Barmar Jul 17 '15 at 15:54
  • 1
    I guess you just need to change $PATH. – mikeserv Jul 17 '15 at 16:16
  • I'm not sure how homebrew installs GNU coreutils but other package managers and if you were to install GNU coreutils without a package manager then the prefix/libexec/gnubin should be installed. Which is a directory with symbolic links to the binaries prefixed with a g. That directory would be the first one in your PATH. – fd0 Jul 17 '15 at 16:22
  • chroot perhaps? – glenn jackman Jul 17 '15 at 16:26
  • 1
    @glennjackman: chroot is awfully heavy-handed for this. Your entire Linux working environment would have to be copied or linked into that chroot for this to work. You couldn't confidently use GNU grep on ~/Documents instead of BSD grep, for example, without making it available there, too. And then what happens if you want to go grepping around in /Library/Application Support? Potentially the whole system needs to be chrooted. – Warren Young Jul 17 '15 at 16:41
  • 2
    Have you considered @mikeserv alternative? Having your coreutils bin path (and possibly a tweak of scripts that set their own PATH variable) should be enough to keep you going. – Braiam Jul 17 '15 at 16:44
  • 3
    Of course the real solution would be to write portable scripts in the first place... – mikeserv Jul 17 '15 at 17:12
  • @mikeserv, do you recommend any specific resources for writing portable scripts? – Steven C. Howell Jul 19 '15 at 04:01

2 Answers2

7

First, this is about a lot more than just coreutils. The BSD equivalent to GNU findutils is also quite different, pretty much every command related to dynamic linkage is different, etc.

And then on top of that, you have to deal with versioning differences: OS X still ships a lot of older software to remain on GPL2 instead of GPL3, such as Bash 3.x instead of Bash 4.x. The autotools are also often outdated with respect to bleeding-edge Linux distros.

The answer to the core part of your question is, "Sure, why not?" You can use Homebrew to install all of these alternative GNU tools, then put $(brew --prefix coreutils)/libexec/gnubin and /usr/local/bin first in your PATH to make sure they're found first:

export PATH="$(brew --prefix coreutils)/libexec/gnubin:/usr/local/bin:$PATH"

If for some reason brew installs a package to another location, also include that in the PATH variable.

If you would rather only replace a few packages, the tricky bit is dealing with all the name changes. Whenever brew installs a program that already has an implementation in the core OS, such as when installing GNU coreutils, it names its version differently so that you can run either, depending on your need at the time. Instead of renaming all of these symlinks¹, I recommend that you fix all of this up with a layer of indirection:

$ 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...

Once you're happy with your new environment, you can put export PATH=$HOME/linux:$PATH into your ~/.bash_profile.

That takes care of interactive use, either with bulk replacement or single application replacement.

Unfortunately, it does not completely solve the shell script problem, because sometimes shell scripts get their own environment, such as when launched from cron. In that case, you could modify the PATH at the top of each cross-platform shell script:

#!/bin/bash
export PATH="$HOME/linux:$(brew --prefix coreutils)/libexec/gnubin:/usr/local/bin:$PATH"

You do not need to make it conditional, since it is just offering the shell another place to look for programs.


Footnotes

  1. e.g. /usr/local/bin/gmv../Cellar/coreutils/$version/bin/gmv

Related Posts

  1. How to replace Mac OS X utilities with GNU core utilities?
  2. Install and Use GNU Command Line Tools on Mac OS X
Warren Young
  • 72,032
  • I added the option for bulk replacement of utilities and links to other posts I found helpful. Thank you for pointing me in the right direction. – Steven C. Howell Jul 20 '15 at 13:59
-1

Puting this answer here as something you would try if running GNU is impossible to run natively alongside freebsd without using VM box or duel boot.

As stated, homebrew cannot install all the GNU coreutils and correct me if I am wrong, but you also want to be able to have all your files at one place(one mechine)

If you have a secondary computer connected to the Internet (perhaps a raspberry pi? ), you can SSH into the linux mechine from you mac or If you want to use the X-environent, you can use x11vnc to use the linux computer on your mac.

Keep in mind, If you use SSH, you can only access the login shell.

How to create a SSH server and client

First off check if openssh server is running on your linux mechine

$ service ssh status

Of the service is running, you'll get an output like this.

    ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2015-07-17 16:51:08 NPT; 5h 21min ago
  Process: 1669 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 615 (sshd)
   CGroup: /system.slice/ssh.service
           └─615 /usr/sbin/sshd -D

If the service isn't running, first check if openssh is installed

sudo apt-get install openssh

then start the service

sudo service ssh start

And all done! (unless ofcourse you want to create keys)

Now you can log in to your linux mechine through SSH as such

ssh <USERNAME_ON_LINUX_MECHINE>@<LINUX_HOST_NAME>

The linux host name is mostly the External IP address of the mechine.

(Ofcourse, you need openssh installed on your mac as well)

Here's a complete tutorial on SSH tunneling

http://inside.mines.edu/fs_home/gmurray/HowTo/sshNotes.html

How to use a x11vnc Server and client

I take vnc to be a better form of SSH (my personal opinion) VNC is easier to install then SSH

Here's a link to arch-wiki for setting up vnc https://wiki.archlinux.org/index.php/X11vnc

  • installing x11vnc

    sudo apt-get install x11vnc

  • Create a password for your user:

    x11vnc -storepasswd

  • If you have ssh setup you can use it to start x11vnc assuming you are logged in already, but remember to tell it to use your password file:

    x11vnc -usepw

Assuming you are using lightdm for the login you can fix this problem you can start x11vnc with the command:

sudo x11vnc -xkb -noxrecord -noxfixes -noxdamage -display :0 -auth /var/run/lightdm/root/:0 -usepw
Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
  • While I agree that "If you want Linux, you know where to find it," is a reasonable answer to the problem, this is not the way I'd go about it. I'd use a VM instead. But the real problem I have with this line of reasoning is that it simply doesn't answer the question as-asked. The OP wants a Linux-like environment on OS X. – Warren Young Jul 17 '15 at 16:47
  • This doesn't answer the question. The question is "how can I make my MacOS environment more like GNU/Linux" and your answer is "Don't — just log into a GNU/Linux system instead". – Celada Jul 17 '15 at 16:48
  • the OP wants to leave the system intact " Is it possible to install/setup a separate bash environment to use only the GNU coreutils while leaving the system Free-BSD ones in place?" and setup another environment alongside it. The simplest way would be to either use a VM box as @WarrenYoung said but VNC would be better since all the files would be intact and in one place. – ayushjha Jul 17 '15 at 16:53