That’s what Mark meant to say, anyway. The article is spot on. The title – lacking precision.

I'm not one of those GNU nazis [I know too many people whose opinion I respect that wouldn’t appreciate being called a “nazi” for their position on this —Ed] who thinks any mention of “Linux” must be prefixed with “GNU/” but, here, we are talking specifically about core userland and, in my considered opinion, GNU owns when it comes to core userland and should be credited as such.

I can’t think of single piece (package?) of software I use, admire, and depend on more than GNU Coreutils. Maybe Firefox. Maybe OpenSSH. Some days rsync(1).

I don’t use Linux very often, either. My kids use an old Dell laptop that runs Ubuntu (they let me play with apt-get every once in awhile) and we have a couple of Fedora boxes at work. I use FreeBSD a lot. FreeBSD, FreeBSD, FreeBSD. FreeBSD everywhere, in fact. And I've been running MacOS X on my lap for a couple of years now. Which is, you know, more BSD.

And that brings me to the reason I wanted to comment on Mark’s article in the first place:

The next generation is cutting their teeth on GNU/Linux, not Solaris. Sorry, BSD.

You can get the GNU without the Linux. Most GNU stuff runs fine on BSD and I think I remember Tim mentioning at some point that one of the first things he does on all that Sun gear he gets to play with is get a proper GNU userland setup. The problem is that you can’t replace the core userland on most Unices with GNU’s userland due to all the compatibility issues.

On both FreeBSD and MacOS X (with MacPorts), the GNU core utilities are installed with a frustrating “g” prefix. So cat is gcat, tail is gtail, sort is gsort and so forth. When I first encountered this heresy, I did this:

$ sudo su - root
# cd /usr/local/bin
# for f in g*; do gln -s $f `echo $f | gsed 's/^g//'`; done

Don’t do that. There’s a lot of FreeBSD stuff that will choke in various odd ways (all bad!) when GNU owns your PATH (sed was the most common culprit, if I remember correctly, and maybe make, too).

Instead, I added the following to my .bashrc (that travels everywhere with me):

# prefer GNU version of most core utilities (interactive shell only).
alias awk=$(type -p gawk gnuawk awk | head -1)
alias base64=$(type -p gbase64 base64 | head -1)
alias basename=$(type -p gbasename basename | head -1)
alias cat=$(type -p gcat cat | head -1)
alias cp=$(type -p gcp cp | head -1)
alias cut=$(type -p gcut cut | head -1)
alias date=$(type -p gdate date | head -1)
alias diff=$(type -p gdiff diff | head -1)
alias df=$(type -p gdf df | head -1)
alias du=$(type -p gdu du | head -1)
alias false=$(type -p gfalse false | head -1)
alias fmt=$(type -p gdu du | head -1)
alias head=$(type -p ghead head | head -1)
alias join=$(type -p gjoin join | head -1)
alias make=$(type -p gmake make | head -1)
alias md5sum=$(type -p gmd5sum md5sum | head -1)
alias mv=$(type -p gmv mv | head -1)
alias nl=$(type -p gnl nl | head -1)
alias paste=$(type -p gpaste paste | head -1)
alias printf=$(type -p gprintf printf | head -1)
alias readlink=$(type -p greadlink readlink | head -1)
alias rm=$(type -p grm rm | head -1)
alias seq=$(type -p gseq seq | head -1)
alias sha1sum=$(type -p gsha1sum sha1sum | head -1)
alias sleep=$(type -p gsleep sleep | head -1)
alias sort=$(type -p gsort sort | head -1)
alias split=$(type -p gsplit split | head -1)
alias tac=$(type -p gtac tac | head -1)
alias tail=$(type -p gtail tail | head -1)
alias tar=$(type -p gnutar gtar tar | head -1)
alias tee=$(type -p gtee tee | head -1)
alias touch=$(type -p gtouch touch | head -1)
alias tr=$(type -p gtr tr | head -1)
alias true=$(type -p gtrue true | head -1)
alias uniq=$(type -p guniq uniq | head -1)
alias uptime=$(type -p guptime uptime | head -1)
alias wc=$(type -p gwc wc | head -1)
alias who=$(type -p gwho who | head -1)
alias whoami=$(type -p gwhoami whoami | head -1)
alias yes=$(type -p gyes yes | head -1)

What that does, basically, is makes anything entered into an interactive shell session use GNU stuff if it’s there. And since these are aliases set up in .bashrc, they have no effect on other programs launched from the command line or elsewhere (e.g., cron).

Lastly, if you need GNU’s core utilities for a specific script, you can use the same alias technique (just put the ones you need in the script itself). The other way to use GNU stuff for specific scripts is to create a directory full of symlinks to the g* version (like we did in /usr/local/bin above) and then put that directory on your PATH, directly in the script:

PATH="/usr/gnu/bin:$PATH"

I typically try to keep my scripts to spec so its less of an issue there. We've standardized on GNU in the backroom at work, though, where we do a lot of ETL type stuff, and we use this technique. The thinking is that we can take the GNU userland to any platform in the future, whereas we'd be tied to certain kernel by any other userland.

So, yea. The GNU userland is killing the Solaris userland and all the other userlands, as planned. Linux gets a lot of credit for being a catalyst for that but GNU is extremely portable, feature rich, and well designed. It’s not like this is a free ride on the Linux express.

This entry has been tagged foss, solaris, bsd, freebsd, coreutils, gnu, unix, coding — follow a tag for related essays, articles, and bookmarks.

Discuss

  1. You make a good point. I've been told by others that htop runs on BSD, and the main thrust of my argument are the small differences between the GNU userland tools, as you point out.

    If I ever find myself in a BSD shop where my brain doesn’t need to retrain to myriad small differences in tooling, then I likely won’t be writing a blog article like the one you've reflected on :)

    Mark

    Mark Turansky on Sunday, March 02, 2008 at 12:41 PM #

  2. Great aliases, I just put them into my .zshrc :–)

    Yi Qiang on Sunday, March 02, 2008 at 02:17 PM #

  3. Mark: I somehow forgot to mention that I run htop on my x86 FreeBSD installs (it doesn’t work on amd64). Here’s the port. But get this – it requires “linprocfs”, which is basically Linux’s /proc emulated on FreeBSD.

    Ryan Tomayko on Sunday, March 02, 2008 at 07:11 PM #

  4. I hate the nightmare of Solaris 10’s gnu/non gnu compiling/linking comflicts. Some things need the gnu toolchain to compile, or need modules/libraries compiled with the gnu toolchain. It just becomes a mess!

    Anko on Monday, March 03, 2008 at 05:58 PM #

  5. I am glad I am not the only one who runs some *bsd boxes and prefers Gnu userland.

    And thanks for the alias script (I did a lot uglier hack by symlinking them to my ~/bin) It’s so obvious now that I think about it.

    Thanks again

    Luka Marinko on Saturday, March 22, 2008 at 06:17 AM #

  6. “You can get the GNU without the Linux. Most GNU stuff runs fine on BSD ” GNU/kBSD in the Debian project is GNU as the userland on top of the BSD kernel. I eventually figured out a userland/kernel syntax. With this syntax any OS that have a GNU userland must be called GNU/*.

    Yuhong Bao on Saturday, April 05, 2008 at 02:15 AM #

  7. Oh, now that’s interesting. I'd never heard of the Debian GNU/kFreeBSD port.

    I eventually figured out a userland/kernel syntax.

    What do you call the stock FreeBSD userland? Just “FreeBSD” or “BSD”?

    With this syntax any OS that have a GNU userland must be called GNU/*.

    Is that you, Richard Stallman? If so, that sure is an interesting new tact you've taken to there.

    Ryan Tomayko on Saturday, April 05, 2008 at 02:57 PM #

  8. How about the following?

    make_gnu_aliases() {
      local cmd
      local gcmd
      for gcmd in /opt/csw/bin/g*
      do
        cmd=${gcmd##*/g}
        if [[ "$(type -p ${cmd})" ]]; then
          alias ${cmd}=$(type -p g${cmd} ${cmd} | head -1)
        fi
      done
    }
    make_gnu_aliases
    

    You then would automatically get all the currently installed utilities, you wouldn’t miss gfind and gsed, and you wouldn’t have fmt aliased as gdu.

    Automatthias on Sunday, March 15, 2009 at 09:56 AM #

  9. I have installed ‘coreutils @7.4_0+with_default_names (active)’ using MacPorts on MacOSX 10.5. Thus far, I have not experienced conflicts. But, I may uninstall it, install it again without default names, and use aliases just to be safe.

    iTerm (256 colours) + MacPorts + coreutils = Awesome

    SpookyET on Thursday, June 04, 2009 at 09:41 PM #

  10. I use the GNU utils on Windows, and don’t once think about that it’s the GNU utils. I just think in terms of grep, cut, wc, etc. So should I call this GNU/Windows??

    Almost all Windows users (not that you care what we think) will think of the GNU/Linux vs Linux controversy as being totatally absurd. Linux is now and will in the future be the sole name of the OS. Stallman deserves great credit for what he has done, but that credit doesn’t include naming rights when the name thus constructed is awkward.

    The GNU/Linux vs Linux naming debate is typical of the theoretical, abstract, totally time wasting discussions that Linux and Unix snobs tend to partake in. I am reminded of the abstract comparison to theologians discussing how many angels can dance on the head of a pin.

    itsme on Friday, July 03, 2009 at 05:22 AM #

Leave a comment





(syntax: markdown)