270

I found there is some differences between the utility command I used on the mac OSX and linux. I want to make my experience united.

How could I replace all my mac utilities with GNU utilities?

5

7 Answers 7

313

This adds symlinks for GNU utilities with g prefix to /usr/local/bin/:

brew install coreutils findutils gnu-tar gnu-sed gawk gnutls gnu-indent gnu-getopt grep

See brew search gnu for other packages. If you want to use the commands without a g prefix add for example /usr/local/opt/coreutils/libexec/gnubin before other directories on your PATH.

$ brew info coreutils
coreutils: stable 8.21
http://www.gnu.org/software/coreutils
Depends on: xz
/usr/local/Cellar/coreutils/8.20 (208 files, 9.4M)
/usr/local/Cellar/coreutils/8.21 (210 files, 9.6M) *
https://github.com/mxcl/homebrew/commits/master/Library/Formula/coreutils.rb
==> Caveats
All commands have been installed with the prefix 'g'.

If you really need to use these commands with their normal names, you
can add a "gnubin" directory to your PATH from your bashrc like:

    PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"

Additionally, you can access their man pages with normal names if you add
the "gnuman" directory to your MANPATH from your bashrc as well:

    MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH"
0
66

Besides brew install coreutils, you may also need to install some other packages, such as gnu-sed, grep:

brew install findutils
brew install gnu-indent
brew install gnu-sed
brew install gnutls
brew install grep
brew install gnu-tar
brew install gawk

Note that the --with-default-names option is removed since January 2019, so each binary has to be added to the path if they are to be used without the g prefix.

Old reference (when --with-default-names was available): http://www.topbug.net/blog/2013/04/14/install-and-use-gnu-command-line-tools-in-mac-os-x/

3
  • Note that brew install gawk (unlike all the others) will replace awk (via a symbolic link /usr/local/bin/awk). If you want to keep the original /usr/bin/awk, just rm /usr/local/bin/awk
    – wisbucky
    Commented Jun 1, 2019 at 10:48
  • Is there a GNU version of ping available?
    – HappyFace
    Commented Mar 16, 2021 at 14:46
  • @HappyFace I don't think so. On GNU/Linux, ping is a Linux kernel utility: github.com/iputils/iputils
    – xuhdev
    Commented Mar 16, 2021 at 21:19
25

I'm not sure that I would recommend replacing them; however, you can install them to a different path and utilize them that way. Overall, if you are coming from Linux and would like access to more "generic" *nix utilities, and a system similar to apt, then I would recommend looking into Macports: http://www.macports.org

It allows, for example, using the latest "generic" GCC, as opposed to/in addition to Apple's included GCC, just as an example.

4
  • 3
    For instance, tar and zip from Mac OS X know about metadata that the GNU versions do not.
    – lhf
    Commented Oct 22, 2012 at 17:49
  • 1
    There are Apple supplied apps, which are just GUIs for some command line tools and if you replace them the apps may start behaving strangely, so go with adding, not replacing.
    – Ɱark Ƭ
    Commented Oct 23, 2012 at 11:56
  • Right; something like Macports adds them, it doesn't replace them.
    – Jonathan
    Commented Oct 23, 2012 at 12:10
  • 3
    If you want to use the GNU utilities by default with MacPorts you can add /opt/local/libexec/gnubin to the front of your PATH environment variable.
    – markshep
    Commented Sep 26, 2016 at 11:59
12

I have written a script that transparently transforms the macOS CLI into a fresh GNU/Linux CLI experience by

  • installing missing GNU programs
  • updating outdated GNU programs
  • replacing pre-installed BSD programs with their preferred GNU implementation
  • installing other programs common among popular GNU/Linux distributions

https://github.com/fabiomaia/linuxify

git clone https://github.com/fabiomaia/linuxify.git
cd linuxify/
./linuxify install

It also allows you to easily undo everything.

./linuxify uninstall
0
11

I've written a script to do exactly this on Intel macOS! The script can be viewed here (or below). However, I can't always guarantee this post will reflect the latest version of the script linked previously.

Upon running the script, Homebrew will be installed (if not already), all the associated GNU utilities will be installed (if not already), and the PATH variable will be built from the installed utilities.

#!/bin/bash

# Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL "\
"https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Install required packages from Homebrew
brew tap homebrew/dupes
brew install coreutils binutils diffutils ed findutils gawk gnu-indent gnu-sed \
  gnu-tar gnu-which gnutls grep gzip screen watch wdiff wget bash gdb gpatch \
  m4 make nano file-formula git less openssh python rsync svn unzip vim \
  --default-names --with-default-names --with-gettext --override-system-vi \
  --override-system-vim --custom-system-icons

# Empty the .bash_path file that holds GNU paths
[[ -f ~/.bash_path ]] && mv ~/.bash_path ~/.bash_path.orig

brew_prefix=$(brew --prefix)
# Build PATH variable script in ~/.bash_path
for i in ${brew_prefix}/Cellar/*/*/bin; do
  echo 'export PATH="'$i':$PATH"' >> ~/.bash_path
done
for i in ${brew_prefix}/Cellar/*/*/libexec/gnubin; do
  echo 'export PATH="'$i':$PATH"' >> ~/.bash_path
done
for i in ${brew_prefix}/Cellar/*/*/share/man; do
  echo 'export MANPATH="'$i':$MANPATH"' >> ~/.bash_path
done
for i in /${brew_prefix}/Cellar/*/*/libexec/gnuman; do
  echo 'export MANPATH="'$i':$MANPATH"' >> ~/.bash_path
done

# Check if .bash_path is being called from .bash_profile
PATCH=`grep "~/.bash_path" ~/.bash_profile`
if [ "$PATCH" == "" ]; then
  # Add .bash_path to .bash_profile
  echo "source ~/.bash_path" >> ~/.bash_profile
fi
2
  • GET A GRIP. Your script OVERWROTE my ~/.bash_profile. WHY in the heck would it not APPEND to it? I am going to edit your answer Commented Jul 6 at 19:41
  • The problem with adding all the Cellar paths to PATH is that these paths are version-dependent, so after each package update, PATH needs to be adjusted. Most of the commands installed are accessible in $(brew --prefix)/bin which already is in PATH, for the others the method from this answer should work well-enough.
    – nohillside
    Commented Jul 7 at 9:43
2

As an alternative to setting the PATH and MANPATH environment variables (which I would actually recommend), it is also possible to symlink binaries to an existing PATH location like this:

You need to know where Homebrew installs coreutils binaries.

/usr/local/opt/coreutils/bin

The /usr/local/opt directory is where Homebrew stores relatively static files that are unlikely to change between updates.

Then you can create symbolic links from there to a location that is already on your PATH. It must be a path that is loaded early on PATH, because the PATH is searched on a first-come, first-serve basis. /usr/local/bin is a good choice based on looking at echo $PATH.

which sha256sum # prove it is not on PATH
ln -s /usr/local/opt/coreutils/bin/sha256sum /usr/local/bin/
which sha256sum # prove it is on PATH

This way, it would almost as easy to create symbolic links. In some cases, like when you want tighter control, it is a good option rather than adding an entire directory to your PATH and MANPATH.

1

I agree with using brew install coreutils to install the tools. But if you want to use them without the g prefix and are using Oh My Zsh, you can add gnu-utils to your zshrc file to do enable this easily:

plugins=(... gnu-utils)

More info available here: https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/gnu-utils

4
  • How does this impact shell scripts expecting the BSD version of commands?
    – nohillside
    Commented Nov 16, 2022 at 14:55
  • 1
    @nohillside The plugins should be set in your .zshrc file, so their effect should only apply to interactive shells rather than scripts.
    – nofinator
    Commented Dec 15, 2022 at 15:44
  • the only problem I see with this is: what if you want to bring some user scripts that work in a GNU/Linux environment to macOS? Commented Apr 10, 2023 at 14:04
  • Thanks, this solved it for me.
    – d3vCr0w
    Commented Jul 6 at 19:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .